判空新思路

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 请求类型接口,然后是这种校验方式和直接判空,效率会差距多少呢?(橘式疑问)根我思考,如果在校验参数很少的情况下,反射也不会太过于影响性能。

相关推荐
他日若遂凌云志8 分钟前
深入剖析 Fantasy 框架的消息设计与序列化机制:协同架构下的高效转换与场景适配
后端
快手技术24 分钟前
快手Klear-Reasoner登顶8B模型榜首,GPPO算法双效强化稳定性与探索能力!
后端
二闹34 分钟前
三个注解,到底该用哪一个?别再傻傻分不清了!
后端
用户49055816081251 小时前
当控制面更新一条 ACL 规则时,如何更新给数据面
后端
林太白1 小时前
Nuxt.js搭建一个官网如何简单
前端·javascript·后端
码事漫谈1 小时前
VS Code 终端完全指南
后端
该用户已不存在1 小时前
OpenJDK、Temurin、GraalVM...到底该装哪个?
java·后端
怀刃2 小时前
内存监控对应解决方案
后端
码事漫谈2 小时前
VS Code Copilot 内联聊天与提示词技巧指南
后端
Moonbit2 小时前
MoonBit Perals Vol.06: MoonBit 与 LLVM 共舞 (上):编译前端实现
后端·算法·编程语言