Spring MVC:在tomcat中的@ResponseBodyexception处理程序上使用@ResponseStatus(reason =”)

有没有人知道为什么我不能在Spring MVC中的exception处理程序上使用@ResponseStatus(reason = "My message") ,同时仍然返回@ResponseBody。 似乎发生的是,如果我使用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 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 reallyNotFoundHandler(ReallyNotFoundException e){ return Collections.singletonMap("message", e.getMessage()); } 

这个例子的代码在github上结束了。

看来这是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:

对于记录,自从Spring 3.2以来,这变得更糟,因为AnnotationMethodHandlerExceptionResolver已被ResponseStatusExceptionResolver替换,它确实:

 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(); } 

这值得一个bug报告。 此外,使用@ResponseStatus记录了setStatus并且设计不合理。 它应该被称为@ResponseError

我最终为此创造了两个问题: SPR-11192和SPR-11193 。

差不多一年过去了,我的两个问题仍然存在。 我不认为Spring WebMVC是一个一流的REST框架,它不是imho,Web MVC是为了humas而不是机器:-(