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而不是机器:-(