JSR303——数据校验&统一响应数据格式

1.JSR303简介

  • 适用于服务器端的数据校验
  • Java为Bean数据合法性校验所提供的标准框架 
  • Spring MVC支持JSR 303标准的校验框架 
  • JSR 303通过在Bean属性上标注校验注解指定校验规则
  • Spring本身没有提供JSR 303的实现,他是由Hibernate Validator 实现与spring整合的

2. JSR303相关常用的注解

@Null(message) 被注释的元素必须为null
@NotNull(message)被注释的元素必须不为null
@AssertTrue(message)被注释的元素必须为 true
@AssertFalse(message) 被注释的元素必须为 false
@Min(value,message) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value,message)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value,message)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value,message)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min,message) 被注释的元素的大小必须在指定的范围内
@Digits(integer,fraction,message) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past(message) 被注释的元素必须是一个过去的日期
@Future (message)被注释的元素必须是一个将来的日期
@Pattern(regexp="正则表达式",message)使用正则表达式进行匹配
@Email被注释的元素必须是电子邮件地址
@Length(max=5,min=1,message="长度在1~5")检查所属的字段的长度是否在min和max之间,只能用于字符串
@Range  被注释的元素必须在合适的范围内 
@CreditCardNumber对信用卡号进行一个大致的验证
@NotBlank 不能为空,检查时会将空格忽略
@NotEmpty不能为空,这里的空是指空字符串
属性:message="验证提示信息"

3.开发步骤

        01.引入相关依赖(没写版本号的时候会默认使用springboot的版本)

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        02.使用注解:给需要验证的属性增加相应的校验注解

    @NotNull(message = "用户名不能为空")
	private String userName; //用户名称

	@Pattern(regexp = "^[a-zA-Z0-9]{6,8}$",message = "密码必须是6-8位数字和字母的组合")
	private String userPassword; //用户密码

	@Past(message = "生日只能是过去的日期")
	private Date birthday;  //出生日期

	@Min(value = 1, message = "年龄最小值为1")
	@Max(value = 120, message = "年龄最大值120")
	private Integer age;

        03.在controller层中的业务方法参数列表前使用@Valid注解,并且在参数值添加BindingResult参数

        如果没有BindingResult参数,spring会在校验不通过时出现异常

    @PostMapping("/login2")
    public ReturnResult login2(@Valid @RequestBody User user, BindingResult result){
        。。。
    }

        04.BindingResult(校验结果对象)常用方法:

hasFieldErrors("属性名")判断对应的属性是否符合验证,返回布尔值 有:true
hasErrors()判断使用验证的所有的属性验证是否有错,返回布尔值 有:true
getFieldError("属性名")获取有错误的属性对象,返回FieldError类型
fieldError.getDefaultMessage()获取错误属性对象的message提示信息,返回String类型
fieldError.getField()获取错误属性对象的属性名;返回String类型
getFieldErrors()获取所有不符合验证的属性对象,返回List<FieldError>类型

代码演示 :

@PostMapping("/login2")
    public ReturnResult login2(@Valid @RequestBody User user, BindingResult result){
        ReturnResult returnResult=null;
        Map<String,Object> map = new HashMap<>();
        //判断birthday是否有错
        System.out.println(result.hasFieldErrors("birthday"));
        //判断userPassword是否有错
        System.out.println(result.hasFieldErrors("userPassword"));
        //判断是否有错
        if(result.hasErrors()){
            //获取所有的错误
            result.getFieldErrors().forEach((item)->{
                //获取错误信息
                String message = item.getDefaultMessage();
                //获取错误的属性名
                String field = item.getField();
                map.put(field,message);
            });
        }
        return map;
    }

4.封装统一的返回数据格式:ReturnResult<T>

        01.创建ReturnResult类:和前端交互的统一格式类

package com.ck.vo;
import java.io.Serializable;
/***
 * created by lxl
 *  只要这个类会被用来做数据传递(前端<->后端)
 * 和前端接口交互的统一格式
 */
public class ReturnResult implements Serializable{

    //用户查询 正确:{code:200,message:操作成功,data:{用户信息}}
    //用户查询 错误:{code:500,message:后端服务器出错,data:null}

    //状态码 自定义
    private Integer code;
    //提示信息
    private String message;
    //返回数据
    private Object data;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

        02.创建ReturnResultUtils 统一返回工具类

package com.ck.vo;

import org.springframework.stereotype.Component;


/***
 * created by lxl
 *
 * 统一返回工具类
 */
@Component
public class ReturnResultUtils{

    /***
     * 成功 不带数据
     * @return ReturnResult
     */
    public static ReturnResult returnSuccess(Integer code, String message){
        ReturnResult returnResult=new ReturnResult();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        return returnResult;
    }
    /***
     * 成功 带数据
     * @return ReturnResult
     */
    public static ReturnResult returnSuccess(Integer code, String message, Object data){
        ReturnResult returnResult=new ReturnResult();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        returnResult.setData(data);
        return returnResult;
    }
    /***
     * 失败 不带数据
     * @return ReturnResult
     */
    public static ReturnResult returnFail(Integer code, String message){
        ReturnResult returnResult=new ReturnResult();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        return returnResult;
    }

    /***
     * 失败 带数据
     * @return ReturnResult
     */
    public static ReturnResult returnFail(Integer code, String message, Object data){
        ReturnResult returnResult=new ReturnResult();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        returnResult.setData(data);
        return returnResult;
    }
}

        03.修改controller返回值

    @PostMapping("/login2")
    public ReturnResult login2(@Valid @RequestBody User user, BindingResult result){
        ReturnResult returnResult=null;
        Map<String,Object> map = new HashMap<>();
        //判断birthday是否有错
        System.out.println(result.hasFieldErrors("birthday"));
        //判断userPassword是否有错
        System.out.println(result.hasFieldErrors("userPassword"));
        //判断是否有错
        if(result.hasErrors()){
            //获取所有的错误
            result.getFieldErrors().forEach((item)->{
                //获取错误信息
                String message = item.getDefaultMessage();
                //获取错误的属性名
                String field = item.getField();
                map.put(field,message);
            });
            //使用带参数的方法,传入获取到的校验错误信息map,响应给前端
            returnResult= ReturnResultUtils.returnFail(500,"操作失败",map);
        }else{
            returnResult = ReturnResultUtils.returnSuccess(200,"操作成功");
        }
        //返回returnResult统一格式类
        return returnResult;
    }

将ReturnResult类和ReturnResultUtils使用泛型化

        ReturnResult类:将响应数据类型使用泛型约束,在controller中可以规定每一个ReturnResult返回的数据date类型

package com.ck.vo;
import java.io.Serializable;
/***
 * created by lxl
 *  只要这个类会被用来做数据传递(前端<->后端)
 * 和前端接口交互的统一格式
 */
public class ReturnResult<T> implements Serializable{

    //用户查询 正确:{code:200,message:操作成功,data:{用户信息}}
    //用户查询 错误:{code:500,message:后端服务器出错,data:null}

    //状态码 自定义
    private Integer code;
    //提示信息
    private String message;
    //返回数据
    private T data;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

ReturnResultUtils工具类

package com.ck.vo;

import org.springframework.stereotype.Component;


/***
 * created by lxl
 *
 * 统一返回工具类
 */
@Component
public class ReturnResultUtils<T>{

    /***
     * 成功 不带数据
     * @return ReturnResult
     */
    public  ReturnResult<T> returnSuccess(Integer code, String message){
        ReturnResult<T> returnResult=new ReturnResult<>();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        return returnResult;
    }
    /***
     * 成功 带数据
     * @return ReturnResult
     */
    public  ReturnResult<T> returnSuccess(Integer code, String message, T data){
        ReturnResult<T> returnResult=new ReturnResult<>();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        returnResult.setData(data);
        return returnResult;
    }
    /***
     * 失败 不带数据
     * @return ReturnResult
     */
    public  ReturnResult<T> returnFail(Integer code, String message){
        ReturnResult<T> returnResult=new ReturnResult<>();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        return returnResult;
    }

    /***
     * 失败 带数据
     * @return ReturnResult
     */
    public  ReturnResult<T> returnFail(Integer code, String message, T data){
        ReturnResult<T> returnResult=new ReturnResult<>();
        returnResult.setCode(code);
        returnResult.setMessage(message);
        returnResult.setData(data);
        return returnResult;
    }
}

    ———————————跳转全局处理异常&全局数据保存————————————

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值