我們常用@Valid做數(shù)據(jù)校驗(yàn),比如現(xiàn)在前端要新增一個(gè)用戶抱慌,我們可以這樣校驗(yàn):
@RestController
public class UserController {
@PostMapping("/user")
public void addUser(@RequestBody @Valid RequestDTO requestDTO){
//其余業(yè)務(wù)處理
System.out.println(requestDTO.toString());
}
}
傳入的數(shù)據(jù)規(guī)則如下列代碼所示:
@Data
public class RequestDTO {
@NotNull(message = "名字不能為空")
String name;
@NotEmpty(message = "密碼不能為空")
String password;
@Override
public String toString() {
return "name=" + name + ",password=" + password;
}
}
假設(shè)我們模仿前端偽造了一個(gè)非法數(shù)據(jù)(例如密碼為空):
{
"name": "string",
"password": ""
}
加了@Valid注解的程序就能按我們的預(yù)期報(bào)錯(cuò):
{
"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"
}
報(bào)錯(cuò)信息改進(jìn)
但這樣的報(bào)錯(cuò)信息明顯太冗余了,我們想簡(jiǎn)化下眨猎,只拋出有問(wèn)題字段的報(bào)錯(cuò)信息抑进,這回就可以結(jié)合我們的全局異常進(jìn)行處理:
1.編寫(xiě)自定義異常處理類,綁定要處理的異常
這里我們注意到@Valid拋出的異常類是MethodArgumentNotValidException 睡陪,所以我們將捕獲該異常寺渗,并對(duì)它重新自定義異常信息
@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() );
}
}
上面的代碼就是取出里面的報(bào)錯(cuò)信息,組裝成自己需要顯示的信息(這里我們封裝成一個(gè)json結(jié)構(gòu)兰迫,包括狀態(tài)碼和信息返出去):
- 試驗(yàn)成果
將剛剛的請(qǐng)求再發(fā)一遍信殊,現(xiàn)在就可以看到,錯(cuò)誤信息已經(jīng)按照我們規(guī)定的格式返回了:
{
"code": -1,
"msg": "密碼不能為空汁果!"
}