【Java】Java JSR303应用解决数据校验问题,解放双手

发布时间:2024年01月24日

JSR303

JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

Hibernate 对其实现

Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

注解类型描述
@NotNull任何类型属性不能为null
@NotEmpty集合集合不能为null,且size大于0
@NotBlank字符串、字符字符类不能为null,且去掉空格之后长度大于0
@AssertTrueBoolean布尔属性必须是true
@Min数字类型限定数字的最小值(整型)
@Max同@Min限定数字的最大值(整型)
@DecimalMin同@Min限定数字的最小值(字符串,可以是小数)
@DecimalMax同@Min限定数字的最大值(字符串,可以是小数)
@Range数字类型限定数字范围(长整型)
@Length字符串限定字符串长度
@Size集合限定集合大小
@Past时间、日期必须是一个过去的时间或日期
@Future时期、时间必须是一个未来的时间或日期
@Email字符串必须是一个邮箱格式
@Pattern字符串、字符正则匹配字符串

应用

首先是引入依赖

        <!-- JSR303 -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.7.Final</version>
        </dependency>

引入依赖后将我们要进行在controller进行校验的实体类进行注解的添加

import lombok.Data;

import javax.validation.constraints.*;
import java.io.Serializable;
@Data
public class TestDemo implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 品牌id
     */
    @NotNull(message = "修改品牌必须指定品牌Id")
    private Long id;
    /**
     * 品牌名
     */
    @NotBlank(message = "新增品牌名称必须提交")
    private String name;
    /**
     * 介绍
     */
    @NotNull(message = "修改品牌必须指定品牌Id")
    private String descript;
    /**
     * 排序
     */
    @NotNull
    @Min(value=0,message = "排序字段不可小于0")
    private Integer sort;
}

其次是在controller具体的接口方法上对参数添加注解@Validated

    @PostMapping("/test1")
    public Object test1(@Validated @RequestBody TestDemo testDemo)  {
       return  true;
    }

这里使用api调用工具看一下效果
在这里插入图片描述

进阶-注解分组使用

在实体类上标注校验注解的时候,可以给groups属性进行赋值,然后在需要校验的controller类的方法中的实体类前加上@Validated注解,先附上代码再细细说明

首先声明两个空接口

public interface AddGroup {
}
public interface UpdateGroup {
}

这两个接口的作用就是仅用于标记,不需要有任何的方法声明。

为实体类上的注解添加接口标记

在这里插入图片描述

由代码不难看出,每个注解后面我都加上了分组,groups里可以添加多个.class文件,标记对应分组,
这里id和sort这两个字段添加了注解,当在AddGroup分组下的id才会生效,而在UpdateGroup分组下只有sort的校验会生效。

controller具体的接口方法添加分组标记

在这里插入图片描述

当我调用test1方法时对数据进行校验字段只有id会生效,而当我调用test2方法时对数据进行校验字段只有sort生效,可以看一下效果
在这里插入图片描述
在这里插入图片描述

异常类搭配使用

说明:

  • @RestControllerAdvice注解标志了该类会拦截所有异常(具体异常由@ExceptionHandler注解指定,有它注解的方法执行异常处理)并最终以JSON的数据格式返回,参数’basePackages’写明了从哪些包中拦截异常
  • @ExceptionHandler注解表明该方法用来拦截哪些异常,上面代码中创建了两个方法,第一个方法’handleVaildException()'用来专门处理数据校验异常,而第二个方法handleVaildOtheException 用来处理其他所有异常
    如果某个方法标记了特地的处理某个异常,当出现异常时,会由该方法处理,如果没有特定指定某个异常,则会往下跟大范围的方法中去处理,例如Throwable。(第二个方法写的较为粗略,可以根据自己想要返回的数据格式进行封装代码)
@Slf4j
@RestControllerAdvice(basePackages = "com.example.jsr303demo.controller")
public class JSRExceptionControllerAdvice {

    @ExceptionHandler(value={MethodArgumentNotValidException.class})
    public R handleValidException(MethodArgumentNotValidException e){
      log.error("数据校验出现问题{},异常类型{}",e.getMessage(),e.getClass());
        BindingResult bindResult = e.getBindingResult();
        Map<String,Object> resultMap=new HashMap<>();
        bindResult.getFieldErrors().forEach((errorFilad)->{
            String defaultMessage = errorFilad.getDefaultMessage();
            String field = errorFilad.getField();
            resultMap.put(field,defaultMessage);
        });
        return R.error(400,"校验出现问题").put("data",errorMap);
    }


    @ExceptionHandler(value={Throwable.class})
    public R handleException(Throwable e){
        log.error("错误:",e);
        return R.error(401,"未知异常");
    }
}
文章来源:https://blog.csdn.net/pengjun_ge/article/details/135816024
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。