java实现表单必填参数验证的方法
作者:任未然 发布时间:2023-06-16 21:41:24
标签:java,表单,验证
一. 概述
在开发后端接口, 通常都会涉及检验参数必填校验, 一般我们的处理都是很粗暴的写个if()判断, 然后抛异常. 本文将介绍通过代理的思想, 用注解优雅的处理非空判断
二. 实现过程
最终想要的效果->在方法的参数加个注解或者参数的属性里加个注解, 注解可以自定义报错信息, 就可以实现自动非空校验
2.1 编写注解
@Target({ElementType.FIELD}) //作用的位置
@Retention(RetentionPolicy.RUNTIME) //作用域
@Documented
public @interface NotNull {
String value() default "{报错信息}";
}
说明: 该注解用来绑定某个必填属性
@Target({ElementType.TYPE,ElementType.METHOD}) //作用的位置
@Retention(RetentionPolicy.RUNTIME) //作用域
@Documented
public @interface CheckParam {
}
说明: 该注解用来绑定某个类或某个方法,作为校验代理拦截的标识
2.2 编写校验代理AOP
@Aspect
@Slf4j
public class CheckParamAop {
@Around("@within(com.midea.cloud.common.annotation.CheckParam) || @annotation(com.midea.cloud.common.annotation.CheckParam)")
public Object cacheClear(ProceedingJoinPoint pjp) throws Throwable {
try {
MethodSignature signature = (MethodSignature) pjp.getSignature();
// 方法参数注解类型
Annotation[][] parameterAnnotations = signature.getMethod().getParameterAnnotations();
// 方法参数的类型
Class<?>[] parameterTypes = signature.getMethod().getParameterTypes();
// 获取方法参数
Object[] args = pjp.getArgs();
if(!ObjectUtils.isEmpty(args)){
// 遍历参数
AtomicInteger index = new AtomicInteger(0);
Arrays.stream(args).forEach(o -> {
int indexNo = index.getAndAdd(1);
/**
* 检查方法参数非空
*/
Annotation[] parameterAnnotation = parameterAnnotations[indexNo];
if(!ObjectUtils.isEmpty(parameterAnnotation)){
Arrays.stream(parameterAnnotation).forEach(annotation -> {
if(annotation instanceof NotNull){
NotNull notNull = (NotNull)annotation;
// 注解信息
String message = notNull.value();
// 通过工具类获取多语言信息
String localeMsg = LocaleHandler.getLocaleMsg(message);
// 检查参数非空
Optional.ofNullable(o).
filter(o1 -> !ObjectUtils.isEmpty(o1)).
orElseThrow(()->new BaseException(localeMsg));
}
});
}
/**
* 检查方法参数属性非空
*/
Class<?> parameterType = parameterTypes[indexNo];
Field[] fields = parameterType.getDeclaredFields();
if(!ObjectUtils.isEmpty(fields)){
// 遍历属性
Arrays.stream(fields).forEach(field -> {
NotNull annotation = field.getAnnotation(NotNull.class);
if(null != annotation){
Object value = null;
// 注解信息
String message = annotation.value();
// 通过工具类获取多语言信息
String localeMsg = LocaleHandler.getLocaleMsg(message);
Optional.ofNullable(o).orElseThrow(()->new BaseException(localeMsg));
try {
field.setAccessible(true);
value = field.get(o);
} catch (Exception e) {
log.error("获取属性值报错"+e.getMessage());
log.error("获取属性值报错"+e);
}
// value为空时报错
Optional.ofNullable(value).
filter(o1 -> !ObjectUtils.isEmpty(o1)).
orElseThrow(()->new BaseException(localeMsg));
}
});
}
});
}
} catch (BaseException e) {
throw e;
} catch (Exception e){
log.error("检查参数aop报错:"+e.getMessage());
log.error("检查参数aop报错:"+e);
}
return pjp.proceed();
}
}
三. 使用示例
public class Test{
@Data
class Demo{
@NotNull("名字不能为空!")
private String name;
private String sex;
private Integer age;
}
@CheckParam
public void testNoNullCheck1(Demo demo) {
}
@CheckParam
public void testNoNullCheck2(@NotNull("user不能为空") User user) {
}
}
来源:https://www.jianshu.com/p/f2578aef5925
0
投稿
猜你喜欢
- 包含默认敏感词过滤和自定义敏感词过滤。导入依赖<dependency> <groupId>com.git
- Redis中opsForValue()方法的使用1、set(K key, V value)新增一个字符串类型的值,key是键,value是值
- @Autowired注解和静态方法及new关系一、@autowired 与new new出来的对象无法调用@Autowired注入
- 本文实例讲述了C#判断一天、一年已经过了百分之多少的方法。分享给大家供大家参考。具体如下:这里写了四个函数,分别是1.判断当前时间过了今天的
- spring.thymeleaf.cache=false不起作用配置是清除缓存,实现热部署。也就是修改了html后不用重启,刷新页面就能看到
- 1、包装类型是什么?Java 为每一个基本数据类型都引入了对应的包装类型,int 的包装类就是 Integer,从 Java 5 开始引入了
- 本文实例讲述了Java * 和AOP应用。分享给大家供大家参考,具体如下:一 点睛 * 在AOP(Aspect Orient Progr
- 目录1.基于注释声明缓存1.1@EnableCaching1.2@Cacheable1.2.1默认key生成规则1.2.2声明自定义key
- 本章概要返回JSON数据静态资源访问返回JSON数据默认实现JSON 是目前主流的前后端数据传输方式,Spring MVC中使用消息转换器H
- 简介由于最近的项目需求,需要在把配置类导入到容器中,通过查询,使用@Import注解就能实现这个功能,@Import注解能够帮我们吧普通配置
- 最近开发项目中,有个在屏幕上任意拖动的悬浮窗功能,其实就是利用 WindowManager的api来完成这个需求,具体的实现的功能如下:1.
- 目录前言一、技术介绍1.Minio是什么?二、使用步骤1.引入maven库2.封装Minio3.配置文件4.单元测试总结前言使用Spring
- 这篇文章主要介绍了Springboot2.0处理自定义异常并返回json,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考
- 1.@RequestMapping注解1.1@RequestMapping注解的功能从注解名称上我们可以看到,@RequestMapping
- 开发中经常遇到从集合类List、Map中取出数据转换为String的问题,这里如果处理不好,经常会遇到空指针异常java.lang.Null
- 这篇文章主要介绍了Java List分页功能实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- APP生命周期wpf项目目录中有一个App.xaml.cs文件,该文件中App是一个partical类,与之对应的另一partical部分在
- 1.微信配置信息 global.properties2.方法wxpay用于生成预支付订单信息方法notifyWeiXinPay用于微信支付成
- springboot与spring区别一、spring 可以做什么之前已经学习了 spring 的 IOC容器、AOP、springMVC
- MyBatis 获取子类的属性这里有个model类:基类public class user { pu