我使用 Jackson/JSON 很好地设置了 spring REST,一切正常。
但我故意在消息结构中引入了一个错误,导致 400 - 错误请求。但是服务器上没有日志输出。我期望的错误将类似于“Jackson 未知属性异常”或其他任何内容,但它已被捕获并且 400 错误已发送到客户端,但服务器上没有异常日志。
我不想清楚地调试服务器上的所有内容,但我希望像这样清楚地标记为错误的 Spring 网络级异常。
打开它的正确方法是什么?
谢谢!
我使用 Jackson/JSON 很好地设置了 spring REST,一切正常。
但我故意在消息结构中引入了一个错误,导致 400 - 错误请求。但是服务器上没有日志输出。我期望的错误将类似于“Jackson 未知属性异常”或其他任何内容,但它已被捕获并且 400 错误已发送到客户端,但服务器上没有异常日志。
我不想清楚地调试服务器上的所有内容,但我希望像这样清楚地标记为错误的 Spring 网络级异常。
打开它的正确方法是什么?
谢谢!
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handle(HttpMessageNotReadableException e) {
logger.warn("Returning HTTP 400 Bad Request", e);
}
基于@Jukka 的回答,您可以使用@ControllerAdvice
(在 Spring 3.2 中引入)为所有控制器全局启用此功能。它确实需要一些代码,但是根据我的经验,您通常最终还是需要全局错误处理配置,这使您可以设置断点/轻松检查问题。
下面是一个例子:
@ControllerAdvice
public class ControllerConfig {
@ExceptionHandler
@ResponseStatus(HttpStatus.BAD_REQUEST)
public void handle(HttpMessageNotReadableException e) {
log.warn("Returning HTTP 400 Bad Request", e);
throw e;
}
}
万一其他人偶然发现了这个问题,以下在 Spring Boot 2 / Spring 5 中对我有用,并且不需要更改代码。
我将日志级别设置org.springframework.web.servlet.mvc.method.annotation
为DEBUG
。在我的情况下,我在客户端代码中看到 400 个响应,但在服务器端没有日志记录(即使使用自定义错误处理程序)。更改该日志级别后,问题很明显:
DEBUG 172.19.0.16 cs 2018-Jun-08 20:55:08.415 [https-jsse-nio-443-exec-9] - method.annotation.RequestResponseBodyMethodProcessor[line ?] - Read [class java.lang.String] as "application/xml;charset=UTF-8" with [org.springframework.http.converter.xml.MarshallingHttpMessageConverter@2de50ee4]
DEBUG 172.19.0.16 cs 2018-Jun-08 20:55:08.418 [https-jsse-nio-443-exec-9] - method.annotation.ServletInvocableHandlerMethod[line ?] - Failed to resolve argument 0 of type 'java.lang.String'
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'core.dto.RequestDTO' to required type 'java.lang.String'
就我而言,问题出在我的@ControllerAdvice
-annoted 类中,该类扩展了ResponseEntityExceptionHandler
. 当我从一些关于自定义异常处理的随机教程中获得该处理程序代码时,我没有费心去检查那个超类在做什么(我的自定义异常处理工作得很好)。
问题在于ResponseEntityExceptionHandler.handleException()
句柄MethodArgumentNotValidException
以及其他 Spring MVC 异常,将处理逻辑委托给特定的句柄方法。由于我没有为任何此类方法(在本例中handleMethodArgumentNotValid()
)提供返回我自己的响应正文的实现,因此我最终得到了返回带有空正文的响应的默认实现:)。
覆盖您需要的方法或根本不扩展该类。
检查ResponseEntityExceptionHandler 文档以获取已实现的 hanler- 方法列表。
您可以将此属性设置为调试日志级别。
logging.level.org.springframework.web: DEBUG
我不认为扩展 ResponseEntityExceptionHandler 是强制性的。您可以在使用 ExceptionHandler 注释的 ControllerAdvice 类中创建多个处理程序方法,并且可以返回任何类型的响应。请查看以下链接以获取更多详细信息和代码示例。 https://www.thetechnojournals.com/2019/11/how-to-handle-exceptions-in-rest.html