当我使用带有@ControllerAdvice
注释的@ExceptionHandler
时,所有正常的异常处理都不再起作用。所有结果都将显示在标题为“ HTTP状态500 –内部服务器错误”的HTML页面中,并且控制台中未记录任何内容。
我创建了一个简单的@ControllerAdvice
,如下所示,当它无法按预期工作时,我开始尝试basePackages
并从ResponseEntityExceptionHandler
扩展。
@ControllerAdvice(basePackages = "nl.xxxx.events")
public class EventExceptionHandler extends ResponseEntityExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(EventExceptionHandler.class);
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(EventNotFoundException.class)
public void handlePersonNotFound(RuntimeException ex) {
logger.error("error", ex);
}
}
在服务中,我使用以下方法抛出异常:
public Event findById(Long id) {
return this.eventRepository.findById(id).orElseThrow(() -> new EventNotFoundException(id));
}
我尝试比较有和没有@ControllerAdvice
的代码流,但是有很多不同之处。例如,在没有@ControllerAdvice
的情况下,HttpEntityMethodProcessor
的value属性设置了一个描述异常的对象。但是对于@ControllerAdvice
,此属性始终为null
。
我希望上面的代码不会干扰正常的异常处理。
作为一个例子,我想使用“无法初始化代理-没有会话”错误,因为这对我来说很容易复制。
在我添加@ControllerAdvice
弹簧之前,给出了以下json结果:
{"timestamp":"2019-06-02T19:17:14.223+0000","status":500,"error":"Internal Server Error","message":"Could not write JSON: failed to lazily initialize a collection of role: (truncated)....","path":"/events/find"}
并带有调试日志记录:
2019-06-02 21:18:29.723 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.724 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.728 DEBUG 1588 --- [nio-8080-exec-2] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:18:29.729 WARN 1588 --- [nio-8080-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
2019-06-02 21:18:29.729 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error?page=1&size=10", parameters={masked}
2019-06-02 21:18:29.730 DEBUG 1588 --- [nio-8080-exec-2] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:18:29.731 DEBUG 1588 --- [nio-8080-exec-2] o.s.w.s.m.m.a.HttpEntityMethodProcessor : Writing [{timestamp=Sun Jun 02 21:18:29 CEST 2019, status=500, error=Internal Server Error, message=Could not (truncated)...]
2019-06-02 21:18:29.732 DEBUG 1588 --- [nio-8080-exec-2] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 500
但是现在它返回:
<!doctype html><html lang="en"><head><title>HTTP Status 500 – Internal Server Error</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 500 – Internal Server Error</h1></body></html>
并带有调试日志记录:
2019-06-02 21:20:33.682 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : GET "/events/find?page=1&size=10", parameters={masked}
2019-06-02 21:20:33.688 DEBUG 22308 --- [nio-8080-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to public org.springframework.data.domain.Page<nl.xxxx.events.Event> nl.xxxx.events.EventController.findPersons(java.lang.String,java.lang.Integer,java.lang.Integer)
2019-06-02 21:20:33.760 INFO 22308 --- [nio-8080-exec-1] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory
2019-06-02 21:20:33.900 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Using 'application/json', given [application/json, text/plain, */*] and supported [application/json, application/*+json, application/json, application/*+json]
2019-06-02 21:20:33.901 DEBUG 22308 --- [nio-8080-exec-1] m.m.a.RequestResponseBodyMethodProcessor : Writing [Page 1 of 19 containing nl.xxxx.events.Event instances]
2019-06-02 21:20:33.923 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Using @ExceptionHandler public final org.springframework.http.ResponseEntity<java.lang.Object> org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler.handleException(java.lang.Exception,org.springframework.web.context.request.WebRequest) throws java.lang.Exception
2019-06-02 21:20:33.925 DEBUG 22308 --- [nio-8080-exec-1] o.s.w.s.m.m.a.HttpEntityMethodProcessor : No match for [application/json, text/plain, */*], supported: []
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: nl.xxxx.events.Event.schedule, could not initialize proxy - no Session (through reference chain: org.springframework.data.domain.PageImpl["content"]->java.util.Collections$UnmodifiableRandomAccessList[0]->nl.xxxx.events.Event["schedule"])]
2019-06-02 21:20:33.926 DEBUG 22308 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed 500 INTERNAL_SERVER_ERROR
因此,在某些时候它只会说No match for [application/json, text/plain, */*], supported: []
,并且将不再返回漂亮的JSON异常。
关于我在做什么错的任何想法?最初只是希望EventNotFoundException
产生404而不是500。可能在将来,我还要添加内容。
答案 0 :(得分:0)
问题是您试图处理过于普遍的RuntimeException。 public void handlePersonNotFound(RuntimeException ex)
也不需要从ResponseEntityExceptionHandler
扩展。
如果编写应处理特定异常的ExceptionHandler,则handleException方法需要接受该特定异常作为参数。另外,您可能需要某种回复。
@ControllerAdvice
public class EventExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(getClass());
@ResponseBody
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(EventNotFoundException.class)
public String handlePersonNotFound(EventNotFoundException ex) {
logger.error("error", ex);
return ex.getMessage();
}
}
这将为基本的响应正文提供异常消息和错误代码。