주석을 통해 구성된 Spring Boot를 사용하고 있으며 예외 처리기가 catch 할 수없는 오류를 발생시키는 문제가 발생했습니다. 내가 던져지는 오류를 막을 방법을 알았지 만 왜 그것이 작동하는지 전혀 모른다. 컬 curl -v -H "Accept: application/xhtml xml" 'http://localhost:8080/testEndpoint'
와이 예외를 트리거Spring Boot ExceptionHandler 더 많은 오류가 발생했습니다.
@ControllerAdvice
public class MyExceptionAdvice {
...snip...
@ResponseBody
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
void mediaTypeExceptionHandler(HttpMediaTypeNotAcceptableException e) {
logger.info("exception: {}", e.getMessage());
}
}
는 다음과 같은 결과가 기록되는 :
2017-01-24 11:08:20 [http-nio-8080-exec-1] [INFO] MyExceptionAdvice - exception: Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml" -
2017-01-24 11:08:20 [http-nio-8080-exec-1] [WARN] org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver - Failed to invoke @ExceptionHandler method: void MyExceptionAdvice.mediaTypeExceptionHandler(javax.servlet.http.HttpServletRequest,org.springframework.web.HttpMediaTypeNotAcceptableException) - org.springframework.web.HttpMediaTypeNotAcceptableException: Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml"
at org.springframework.web.accept.HeaderContentNegotiationStrategy.resolveMediaTypes(HeaderContentNegotiationStrategy.java:59)
...snip...
2017-01-24 11:08:20 [http-nio-8080-exec-1] [WARN] org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver - Handling of [org.springframework.web.HttpMediaTypeNotAcceptableException] resulted in Exception - java.lang.IllegalStateException: Cannot call sendError() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:472)
...snip...
2017-01-24 11:08:20 [http-nio-8080-exec-1] [ERROR] org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml"] with root cause - org.springframework.web.HttpMediaTypeNotAcceptableException: Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml"
at org.springframework.web.accept.HeaderContentNegotiationStrategy.resolveMediaTypes(HeaderContentNegotiationStrategy.java:59)
...snip...
그리고 클라이언트에 대한 응답은 HTML의 혼란과 스택 추적했다 :
<!DOCTYPE html><html><head><title>Apache Tomcat/8.5.6 - Error report</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 - Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml"</h1><div class="line"></div><p><b>type</b> Exception report</p><p><b>message</b> <u>Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml"</u></p><p><b>description</b> <u>The server encountered an internal error that prevented it from fulfilling this request.</u></p><p><b>exception</b></p><pre>org.springframework.web.HttpMediaTypeNotAcceptableException: Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml"
org.springframework.web.accept.HeaderContentNegotiationStrategy.resolveMediaTypes(HeaderContentNegotiationStrategy.java:59)
...snip...
다른 값을 기록하면서 놀고있는 동안 예외를 매개 변수로 갖기 위해 예외 처리기를 수정했습니다.
@ResponseBody
@ExceptionHandler(HttpMediaTypeNotAcceptableException.class)
void mediaTypeExceptionHandler(HttpServletResponse response, HttpMediaTypeNotAcceptableException e) {
logger.info("exception: {}", e.getMessage());
}
이제는 동일한 컬이 로그를 생성하고 처음에는 예상했던 로그에 오류가 더 이상 발생하지 않습니다.
2017-01-24 11:30:31 [http-nio-8080-exec-1] [INFO] com.gwm.cat2.core.resource.CAT2ExceptionAdvice - exception: Could not parse 'Accept' header [application/xhtml xml]: Invalid mime type "application/xhtml xml": Invalid token character ' ' in token "xhtml xml" -
그리고 클라이언트가받는 응답이 정확합니다.
내 질문은 왜입니까? 응답 객체를 매개 변수로 사용하면 처리기로 전달하기 전에 업스트림에 무언가를 수행합니까? 그것이 일어나지 않는 것은 후속 오류가 다운 스트림에서 발생하는 이유입니다. 감사.
감사합니다. 하지만 그 행동은 예외 처리기의 메서드 서명에 관계없이 일관성이있을 것이라고 기대합니다. 그게 날 여기에서 넘어 뜨리는거야. 응답 객체를 수정하지 않더라도 매개 변수로 자동으로 포함하면 Spring 내부에서 오류를 처리합니다. – ArmedChef