@Valid 数据校验 + 自定义全局异常信息

关于javax.validation.Validator校验的使用

  • 对于要校验的实体类:其需要校验的字段上需要添加注解

常用注解

实际例子

实体类Demo

使用:首先要拿到 validator的子类

Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

其中方法可以参考 API
对实体类的校验

Set<ConstraintViolation<Object>> set = validator.validate(obj,Default.class);
 

本文链接:https://blog.csdn.net/qq_38193966/article/details/95990268

———————————————— 

@Valid 数据校验 + 自定义全局异常信息

我们常用@Valid做数据校验,比如现在前端要新增一个用户,我们可以这样校验:

@RestController
public class UserController {

    @PostMapping("/user") public void addUser(@RequestBody @Valid RequestDTO requestDTO){ //其余业务处理 System.out.println(requestDTO.toString()); } } 

传入的数据规则如下列代码所示:


@Data
public class RequestDTO {
    @NotNull(message = "名字不能为空") String name; @NotEmpty(message = "密码不能为空") String password; @Override public String toString() { return "name=" + name + ",password=" + password; } } 

假设我们模仿前端伪造了一个非法数据(例如密码为空):

{
  "name": "string", "password": "" } 

加了@Valid注解的程序就能按我们的预期报错:

{
  "timestamp": "2019-08-26T14:12:02.542+0000", "status": 400, "error": "Bad Request", "errors": [ { "codes": [ "NotEmpty.requestDTO.password", "NotEmpty.password", "NotEmpty.java.lang.String", "NotEmpty" ], "arguments": [ { "codes": [ "requestDTO.password", "password" ], "arguments": null, "defaultMessage": "password", "code": "password" } ], "defaultMessage": "密码不能为空", "objectName": "requestDTO", "field": "password", "rejectedValue": "", "bindingFailure": false, "code": "NotEmpty" } ], "message": "Validation failed for object='requestDTO'. Error count: 1", "path": "/user" } 

报错信息改进

但这样的报错信息明显太冗余了,我们想简化下,只抛出有问题字段的报错信息,这回就可以结合我们的全局异常进行处理:

1.编写自定义异常处理类,绑定要处理的异常

这里我们注意到@Valid抛出的异常类是MethodArgumentNotValidException ,所以我们将捕获该异常,并对它重新自定义异常信息

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = MethodArgumentNotValidException.class) @ResponseBody public JsonResult MyExceptionHandle(MethodArgumentNotValidException exception){ exception.printStackTrace(); BindingResult result = exception.getBindingResult(); StringBuilder errorMsg = new StringBuilder() ; if (result.hasErrors()) { List<FieldError> fieldErrors = result.getFieldErrors(); fieldErrors.forEach(error -> { System.out.println("field" + error.getField() + ", msg:" + error.getDefaultMessage()); errorMsg.append(error.getDefaultMessage()).append("!"); }); } exception.printStackTrace(); return new JsonResult(-1,errorMsg.toString() ); } } 

上面的代码就是取出里面的报错信息,组装成自己需要显示的信息(这里我们封装成一个json结构,包括状态码和信息返出去):

  1. 试验成果

将刚刚的请求再发一遍,现在就可以看到,错误信息已经按照我们规定的格式返回了:

{
  "code": -1, "msg": "密码不能为空!" }

猜你喜欢

转载自www.cnblogs.com/kelelipeng/p/11994742.html