判空新思路

1.问题:

最近在做接口开发时,遇到了一个问题,如下代码

令人奇怪的是,此处就算前端或者接口文档中,没有传递参数,此处也不会进入这个判断,因为 userLoginRequest 对象并不为空,那么就产生疑问了? 是框架中的哪一部操作帮助我们 new 了一个对象出来呢?(七夕要到了!你 new 对象了吗)

带着疑问,我上网查询了一下,发现这与 SpringMvc 的@RequestBody 有关,那么查看源码后发现,是在这个方法中实现。

readWithMessageConverters

维护了一个 HttpMessageConverter 列表,如果其中某个 HttpMessageConverter 支持给定内容类型的请求体转换为类对象,就使用它读取请求体转换为类对象。

那么这样直接校验是否为空,看来是不可行的,但是如果要一个一个获取出来进行判断校验非空,又感觉很麻烦,那么有没有一种优雅一点的方式获取呢?

2.解决方式:

于是我使用反射的方式配合注解写了个工具类,用于判断参数是否为空,代码如下:

kotlin 复制代码
package com.juzipi.utils;

import org.springframework.beans.factory.annotation.Autowired;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 校验参数是否为空
 *
 * @author juzipi
 * @date 2024/8/6 16:35
 */

public class DataValidationTool<T> {
	public boolean validate(T data) {
		Class<?> clazz = data.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			field.setAccessible(true);
			Annotation[] annotations = field.getAnnotations();
			boolean isNullable = Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType() == Nullable.class);
			try {
				Object value = field.get(data);
				if (value == null && !isNullable) {
					return false;
				}
				
				if (value instanceof String) {
					String strValue = (String) value;
					if (strValue.isEmpty() && !isNullable) {
						return false;
					}
				}
				
				if (value instanceof List) {
					List<?> listValue = (List<?>) value;
					if (listValue.isEmpty() && !isNullable) {
						return false;
					}
				}
				
				if (value instanceof Integer) {
					Integer intValue = (Integer) value;
					if (intValue < 0 && !isNullable)
						return false;
				}
				
				if (value instanceof Long) {
					Long longValue = (Long) value;
					if (longValue < 0 && !isNullable)
						return false;
				}
				if (value instanceof Double) {
					Double doubleValue = (Double) value;
					if (doubleValue < 0 && !isNullable)
						return false;
				}
				
				if (value instanceof Float) {
					Float floatValue = (Float) value;
					if (floatValue < 0 && !isNullable)
						return false;
				}
				
				if (value instanceof Map) {
					Map<?, ?> mapValue = (Map<?, ?>) value;
					if (mapValue.isEmpty() && !isNullable) {
						return false;
					}
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				return false;
			}
		}
		return true;
	}
}
java 复制代码
package com.juzipi.utils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * 自定义可为空字段标识
 *
 * @author juzipi
 * @date 2024/8/6 16:43
 */
@Retention(RetentionPolicy.RUNTIME)
public @interface Nullable {
}

3.使用方式:

写入具体校验实体类的到工具类的泛型中,然后调用 validate 方法,判断返回值即可。

同时,在可以为空的字段上,可以给字段加上 @Nullable 标签,这样就不会去判断该字段了。

4.思考

这样校验真的可以吗?这种校验只适用于 Post 请求类型接口,然后是这种校验方式和直接判空,效率会差距多少呢?(橘式疑问)根我思考,如果在校验参数很少的情况下,反射也不会太过于影响性能。

相关推荐
2401_8576363922 分钟前
计算机课程管理平台:Spring Boot与工程认证的结合
java·spring boot·后端
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
2401_857610035 小时前
多维视角下的知识管理:Spring Boot应用
java·spring boot·后端
代码小鑫5 小时前
A027-基于Spring Boot的农事管理系统
java·开发语言·数据库·spring boot·后端·毕业设计
颜淡慕潇6 小时前
【K8S问题系列 | 9】如何监控集群CPU使用率并设置告警?
后端·云原生·容器·kubernetes·问题解决
独泪了无痕6 小时前
WebStorm 如何调试 Vue 项目
后端·webstorm
怒放吧德德8 小时前
JUC从实战到源码:JMM总得认识一下吧
java·jvm·后端
代码小鑫8 小时前
A025-基于SpringBoot的售楼管理系统的设计与实现
java·开发语言·spring boot·后端·毕业设计
前端SkyRain8 小时前
后端SpringBoot学习项目-项目基础搭建
spring boot·后端·学习
梦想画家8 小时前
理解Rust 生命周期、所有权和借用机制
开发语言·后端·rust