복붙노트

[SPRING] Spring MVC : @ResponseStatus (이유 = '')를 Tomcat의 @ResponseBody 예외 핸들러에서 사용하기

SPRING

Spring MVC : @ResponseStatus (이유 = '')를 Tomcat의 @ResponseBody 예외 핸들러에서 사용하기

@ResponseBody를 반환하면서 Spring MVC의 예외 처리기에서 @ResponseStatus (이유 = "내 메시지")를 사용할 수없는 이유를 아는 사람이 있습니까? 무슨 일이 일어날 것 같다는 이유는 내가 reason 속성을 사용하면

// this exception handle works, the result is a 404 and the http body is the json serialised
// {"message", "the message"}
@ExceptionHandler
@ResponseStatus(value = HttpStatus.NOT_FOUND)
public Map<String, String> notFoundHandler(NotFoundException e){
    return Collections.singletonMap("message", e.getMessage());
}

// this doesn't... the response is a 404 and the status line reads 'Really really not found'
// but the body is actually the standard Tomcat 404 page
@ExceptionHandler
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason = "Really really not found")
public Map<String, String> reallyNotFoundHandler(ReallyNotFoundException e){
    return Collections.singletonMap("message", e.getMessage());
}

이 예제의 코드는 github에서 끝났습니다.

해결법

  1. ==============================

    1.이것은 AnnotationMethodHandlerExceptionResolver의 다음 코드의 직접적인 결과 인 것으로 보입니다.

    이것은 AnnotationMethodHandlerExceptionResolver의 다음 코드의 직접적인 결과 인 것으로 보입니다.

    private ModelAndView getModelAndView(Method handlerMethod, Object returnValue, ServletWebRequest webRequest)
            throws Exception {
    
        ResponseStatus responseStatusAnn = AnnotationUtils.findAnnotation(handlerMethod, ResponseStatus.class);
        if (responseStatusAnn != null) {
            HttpStatus responseStatus = responseStatusAnn.value();
            String reason = responseStatusAnn.reason();
            if (!StringUtils.hasText(reason)) {
                // this doesn't commit the response
                webRequest.getResponse().setStatus(responseStatus.value());
            }
            else {
                // this commits the response such that any more calls to write to the 
                // response are ignored
                webRequest.getResponse().sendError(responseStatus.value(), reason);
            }
        }
        /// snip
    }
    

    이것은 SPR-8251의 Springsource에보고되었습니다 :

  2. ==============================

    2.AnnotationMethodHandlerExceptionResolver가 ResponseStatusExceptionResolver로 대체 되었기 때문에 Spring 3.2 이후의 기록은 더욱 악화되었다.

    AnnotationMethodHandlerExceptionResolver가 ResponseStatusExceptionResolver로 대체 되었기 때문에 Spring 3.2 이후의 기록은 더욱 악화되었다.

    protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, HttpServletRequest request,
      HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
      int statusCode = responseStatus.value().value();
      String reason = responseStatus.reason();
      if (this.messageSource != null) {
        reason = this.messageSource.getMessage(reason, null, reason, LocaleContextHolder.getLocale());
      }
      if (!StringUtils.hasLength(reason)) {
        response.sendError(statusCode);
      }
      else {
        response.sendError(statusCode, reason);
      }
      return new ModelAndView();
    }
    

    이것은 버그 보고서의 가치가 있습니다. 또한 @ResponseStatus는 setStatus로 문서화되어 있으며 잘못 설계되었습니다. @ResponseError라는 이름이어야합니다.

    마지막으로 SPR-11192와 SPR-11193의 두 가지 문제를 만들었습니다.

    거의 1 년이 지났고 두 가지 문제는 아직 열려 있습니다. 나는 Spring WebMVC가 일류가 아닌 일류 REST 프레임 워크라고 생각하지 않는다. WebMVC는 기계가 아니라 유머를위한 것이다.

  3. from https://stackoverflow.com/questions/5637950/spring-mvc-using-responsestatusreason-on-a-responsebody-exception-hand by cc-by-sa and MIT license