自定义注解校验

完结

Posted by xujie on May 21, 2019

正所谓前人栽树,后人乘凉。 感谢Huxpro提供的博客模板 我的的博客

后端数据校验文档

@(后端数据校验文档)[使用规范|使用教程|徐杰|2019年4月25日]

[TOC]

※ 前言

  • 基于现有项目架构都是采用SpringBoot,后端数据校验框架统一使用Spring validation
  • 数据校验应该遵循JSR303/JSR-349这种规范,JSR303是一项标准,JSR-349是升级版本,完善了部分特性以及添加了一些新特性,它们主要提供了一些校验规范(校验注解),如@Null@NotNull@Pattern,这些规范也是可以查找到的,位于javax.validation.constraints包下,只提供规范但是没有提供相关的实现。
  • Hibernate validation是对上述规范的一种实现,而Spring validation是对Hibernate validation的二次封装。
  • 前面说到,Spring validation是对hibernate validation进行二次封装的衍生框架,不同的是,同时在SpringMVC模块中添加了自动校验,并将校验信息封装进了特定的类中,使用方式更简单。
  • 后端数据校验只针对VO实体对象
  • 项目demo已经上传GitHub,地址:https://github.com/xujie007/demo.git

❋使用方式

Maven项目,直接导入相关依赖即可 ```

org.springframework.boot spring-boot-starter-web
> 启动项只需要加入@SpringBootApplication注解即可

@SpringBootApplication public class ValidateApp { public static void main(String[] args) { SpringApplication.run(ValidateApp.class, args); } }


#### ❋具体实现方式
##### ①创建接口返回的实体对象
> - 基于现有项目的实体对象结构,也就不做相关调整了。
> - 返回实体对象四个属性:code(编码),message(提示信息),data(返回数据),serial(序列号,取当前时间戳)
> - 后端数据校验异常的结果全部放在message里面

##### ②创建VO实体以及使用方式
> 我这里创建TestVO对象
@Size(min=2, max=30)
@NotNull
private String name;

@NotEmpty(message = "Email不能为空")
@Email
private String email;
..... ``` > 具体注解查看相关的文档,这里只罗列相关常用的注解 > @Null   被注释的元素必须为 null     @NotNull    被注释的元素必须不为 null     @AssertTrue     被注释的元素必须为 true     @AssertFalse    被注释的元素必须为 false     @Size(max=, min=)   被注释的元素的大小必须在指定的范围内     @Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式     @NotBlank(message =)   验证字符串非null,且长度必须大于0     @Email  被注释的元素必须是电子邮箱地址     @Length(min=,max=)  被注释的字符串的大小必须在指定的范围内     @NotEmpty   被注释的字符串的必须非空     @Range(min=,max=,message=)  被注释的元素必须在合适的范围内
③创建校验异常捕获类

数据校验不通过时,SpringBoot会抛出BindException异常,我们可以捕获这个异常并使用封装的返回实体返回结果。 通过@RestControllerAdvice定义异常捕获类

@RestControllerAdvice
public class BindExceptionHanlder {
    @ExceptionHandler(BindException.class)
    public JsonResponse handleBindException(BindException ex) {
        // ex.getFieldError():随机返回一个对象属性的异常信息。如果要一次性返回所有对象属性异常信息,则调用ex.getAllErrors()
        //List<ObjectError> allErrors = ex.getAllErrors();
        //for(ObjectError error : allErrors){
          // sb.append(error.getDefaultMessage()+",");
        //}
        FieldError fieldError = ex.getFieldError();
                    StringBuilder sb = new StringBuilder();
            sb.append(fieldError.getField()).append("=[").append(fieldError.getRejectedValue()).append("]")
                    .append(fieldError.getDefaultMessage());
        // 生成返回结果
        JsonResponse errorResult = new JsonResponse();
        errorResult.setCode(400);
        errorResult.setMessage(sb.toString());
        return errorResult;
    }
}
④控制层使用方式

控制层使用方式,只需要增加@Validated 注解即可 ``` @RestController public class Test {

@RequestMapping(value = "/test/testM", method = RequestMethod.GET)
public Result saveCustomerPage(@Validated TestVO vo) {
    JsonResponse okResult = new JsonResponse ();
    okResult.setCode(200);
    okResult.setMessage(JSONObject.toJSON(vo).toString());
    return okResult;
}

}


#### ❋自定义数据校验规则
##### ①创建**TokenIsVaildValidator**类

package com.example.demo.annotation;

import org.springframework.util.StringUtils;

import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext;

public class TokenIsVaildValidator implements ConstraintValidator<TokenIsVaild,String> { @Override public void initialize(TokenIsVaild constraintAnnotation) {

}
@Override
public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
	//这个部分,写自己业务逻辑,我这里也只是举个例子
    //校验token是否过期
    if(!StringUtils.isEmpty(s)){
        //第一种方法这里直接从缓存获取token,如果不存在,说明token已经失效
        //TODO
        //第二种方法直接读取配置文件过期时间,然后和当前时间比较大小,如果小于当前时间,则token失效
        //TODO
        return true;

// return false; } return false; } }


##### ②创建**TokenIsVaild**注解

package com.example.demo.annotation;

import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = TokenIsVaildValidator.class ) public @interface TokenIsVaild {

String message() default "token自定义注解";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}


##### ③具体使用方式
>使用方式基本内置的注解使用一样

package com.example.demo.vo;

import com.example.demo.annotation.TokenIsVaild; import lombok.Data;

import javax.validation.constraints.NotBlank;

@Data public class AuthorizationInfo { @NotBlank(message = “授权秘钥不能为空”) @TokenIsVaild(message = “token无效,请重新获取”) String token; } ```

  • 关于后端服务数据校验教程基本已经完毕,这篇文档还属于比较粗糙的版本。如果有不妥之处,望告知!
  • 邮箱:1456204685@qq.com