拦截由@validated 报出的异常MethodArgumentNotValidException并

public class WordsRequest implements Serializable {

    private static final long serialVersionUID = 4048730427527061626L;
    @ApiModelProperty("昵称")
    private String nickname;

    @ApiModelProperty("留言内容")
    @Size(max = 30,min = 1,message = "留言内容过长")
    private String msgContent;

    @ApiModelProperty("消息类型 0 img  1语音  2文字")
    private Integer msgType;

}
 
ResponseEntity> sendWords(
                                                     @Valid @RequestBody WordsRequest  wordsRequest ){
}



我们使用的版本是springboot 2.0.4.RELEASE

我们使用@Valid 验证WordsRequest 入参合法性,但是当msgContent内容长度超过限制30个字符。将响应客户端 

http code 400  Bad Request,并且没有任何错误提示。这样的体验非常得不友好。后端也没有任何日志输出。日志级别是INFO。

但是我们也已经统一拦截所有异常信息,那为啥没有日志打印并且响应请求也是400呢,代码如下。

    @ExceptionHandler(value = {Throwable.class})
    @ResponseBody
    public ResponseEntity constraintViolationHandler(HttpServletRequest req, Throwable exception) {
}

当然我们想看到具体错误原因,才知道情况。 调整日志级别为DEBUG.看到打印日志信息,如下。

org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument at index 3 in method: org.springframework.http.ResponseEntity> crplatform.crp.interfaces.controller.WordsGroupController.sendWords(java.lang.Long,java.lang.String,java.lang.String,crplatform.crp.domain.dto.wordsgroup.WordsRequest), with 1 error(s): [Field error in object 'wordsRequest' on field 'msgContent': rejected value [hello rgregregregregregregregrehh]; codes [Size.wordsRequest.msgContent,Size.msgContent,Size.java.lang.String,Size];

发现具体异常是MethodArgumentNotValidException,这个类。我得到最简单想法是先拦截这个异常类。

    @ExceptionHandler(value = {Throwable.class,MethodArgumentNotValidException.class})

重试部署试一试,但重启异常错误,错误如此下:

Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException]

懵逼了!于是找度娘找到一个答案。https://yq.aliyun.com/articles/398366 

重写父类ResponseEntityExceptionHandler 的方法handleMethodArgumentNotValid

else if (ex instanceof MethodArgumentNotValidException) {
            //这里配置响应请求码400
			HttpStatus status = HttpStatus.BAD_REQUEST;
			return handleMethodArgumentNotValid((MethodArgumentNotValidException) ex, headers, status, request);
		}

/**
	 * Customize the response for MethodArgumentNotValidException.
	 * 

This method delegates to {@link #handleExceptionInternal}. * @param ex the exception * @param headers the headers to be written to the response * @param status the selected response status * @param request the current request * @return a {@code ResponseEntity} instance */ protected ResponseEntity handleMethodArgumentNotValid( MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { //响应体是null,没有数据。 //我们要做得就是重写这个方法。 return handleExceptionInternal(ex, null, headers, status, request); }

重新部署好了。能看到我们自定义的异常信息了-留言信息过长 。

你可能感兴趣的:(springboot)