背景
首先不使用Hibernate-Validator的时候,我们要想校验参数的正确性,需要在Controller里指定
User:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private String email;
    private String password;
    private Integer age;
}
HelloController:
@RestController
@RequestMapping("/user")
public class HelloController {
    @RequestMapping("/add")
    public String add(@RequestBody User user){
        // 参数检查
        if (user.getName() == null || user.getEmail() == null){
            return "error";
        }
        return "success";
    }
}
- 验证代码繁琐,重复劳动
 - 方法内代码显得冗长
 
检验步骤
引入依赖
我们可以使用Hibernate-Validator来简化这些操作,Hibernate Validator是Hibernate提供的一个开源框架,并不是只能在使用Hibernate 的时候来使用
如果使用的是SpringBoot,不需要再引Hibernate-Validator 依赖,因为spring-boot-starter-web包中已经包含了Hibernate-Validator 依赖,如果不是Springboot,可能就要添加对应依赖
  <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.0.7.Final</version>
        </dependency>
注解标识
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    @NotBlank(message = "姓名不能为空")
    private String name;
    @NotBlank
    @Email
    private String email;
    @Min(value = 1, message = "年龄不能小于1")
    @Max(value = 100, message = "年龄不能大于100")
    private Integer age;
}
controller类添加校验注解
@RestController
@RequestMapping("/user")
public class HelloController {
    @RequestMapping("/add")
    public String add(@RequestBody @Valid User user){
        System.out.println(user);
        return "success";
    }
}
如果是单个参数在Controller校验,需要在类上标明@Valid,并且在接收参数上标明校验规则
@RestController
@RequestMapping("/user")
@Valid
public class HelloController {
    @RequestMapping("/add")
    public String add(@NotBlank(message = "姓名不能为空") @RequestParam("name") String name){
        System.out.println(name);
        return "success";
    }
}
返回的错误信息:
{
    "timestamp": "2019-12-21T05:30:38.341+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "Required String parameter 'name' is not present",
    "path": "/test1/user/add"
}
返回结果自定义
如果对默认返回的错误信息不满意,可以使用Spring的@ControllerAdvice来进行异常的捕获。
为了使用方便,我创建了一个序列化的类,用于消息的返回
@JsonSerialize(include =  JsonSerialize.Inclusion.NON_NULL)
@Data
public class ServerResponse<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    private int code;   //状态
    private String msg;   //信息
    private T data;       //数据
    private ServerResponse(int code) {
        this(code,null,null);
    }
    private ServerResponse(int code,T data){
        this(code,null,data);
    }
    private ServerResponse(int code,String msg){
        this(code,msg,null);
    }
    private ServerResponse(int code,String msg,T data){
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public static <T> ServerResponse<T> createByErrorCodeMessage(int errorCode,String errorMessage){
        return new ServerResponse<T>(errorCode,errorMessage);
    }
}
添加ControllerAdvice:
@ControllerAdvice
@ResponseBody
public class CustomAdvice {
    private final static Logger logger = LoggerFactory.getLogger(CustomAdvice.class);
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ExceptionHandler(MissingServletRequestParameterException.class)
    public ServerResponse<String> handleHttpRequestMethodNotSupportedException(Exception e) {
        logger.error("不支持当前请求方法", e);
        return ServerResponse.createByErrorCodeMessage(HttpStatus.METHOD_NOT_ALLOWED.value(),HttpStatus.METHOD_NOT_ALLOWED.getReasonPhrase());
    }
}
此时返回结果就是
{
    "code": 405,
    "msg": "Method Not Allowed",
}
校验注解:
5.png
Tip:三种判断为空的区别
@NotNull:主要用在基本数据类型上(Int,Integer,Double)
举例:
@NotNull(message = “年龄不能为空”)
private Integer age;
@NotBlank:主要用在String字符串上面(String)
举例:
@NotBlank(message = “名字不能为空”)
private String name;
@NotEmpty; 加了@NotEmpty注解的String类 ,Collection集合,Map ,数组,这些是不能为null或者长度为0的;(String ,Collection,Map的isEmpty()方法)










网友评论