Spring 3.1.2使用@ResponseBody的MVC @ExceptionHandler

我正在尝试使用@ResponseBody实现Spring Web MVC @ExceptionHandler以返回包含validation错误的对象。 ( 策略E记录在这里 )。

在Spring 3.0.x中,有一个确认的错误 ,因为已经解决,禁止它正常工作。 我正在使用Spring 3.1.2,不应该遇到那个。

但是,我遇到了一个例外情况“无法找到可接受的代表”。

这是例外:

[10/21/12 12:56:53:296 CDT] 00000045 ExceptionHand E redacted.loggi ng.jdk14.LogWrapper error Failed to invoke @ExceptionHandler method: public redacted.model.view.ValidationErrorResponse redacted.controller.Re stController.handleValidationException(redacted.util.ValidationExceptio n,javax.servlet.http.HttpServletResponse) Originating Class/Method:redacted.web.ui.filter.AccessControlFilter.pr ocessFilter() org.springframework.web.HttpMediaTypeNotAccepta bleException: Could not find acceptable representation at org.springframework.web.servlet.mvc.method.annotation.AbstractMessage ConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMeth odProcessor.java:115) 

这是代码:

 @ExceptionHandler(ValidationException.class) @ResponseStatus(value = HttpStatus.PRECONDITION_FAILED) @ResponseBody public ValidationErrorResponse handleValidationException(ValidationException ex, HttpServletResponse response) { List errs = new LinkedList(); for (ObjectError er : ex.getErrors()) { errs.add(new ValidationError(er.getObjectName(), er.getDefaultMessage())); } return new ValidationErrorResponse(errs); } @RequestMapping(value = "/search") @ResponseBody public SearchResult search(@Valid @ModelAttribute SearchRequest searchRequest, BindingResult bResult) { if (bResult.hasErrors()) { throw new ValidationException(bResult.getAllErrors()); } return searchService.search(searchRequest); } 

有任何想法吗?

如果您正在阅读本文,您可能对我如何使用它有一些疑问。 简短的回答是我不知道。 我从这里恢复了我的代码并重新实现(实际上是复制并粘贴了控制器位),它突然开始工作了。

如果您使用的是Spring 3.1.2,则@ ExceptionHandler和@ResponseBody可以正常工作。

我初步解释为什么它最初不起作用的原因是它可能是一个用户错误或错误(非常复杂,这个应用程序很大)我正在使用的部署脚本。

当我需要为一个以“/blah/blah.xml”之类的已知扩展名结尾的请求返回JSON错误响应时,我遇到了这个问题。 在这种情况下,Spring支持基于扩展的表示匹配,并忽略Accept标头(最新的Spring 4.1.5也是如此)。

无论请求是什么,我都使用以下内容来“锁定”JSON响应。

 @Configuration @EnableWebMvc public class ApplicationConfiguration extends WebMvcConfigurerAdapter { public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorPathExtension(false); configurer.ignoreAcceptHeader(true); configurer.defaultContentType(MediaType.APPLICATION_JSON); } } 

问题似乎是Spring不是如何将ValidationErrorResponse转换为,例如它应该将其转换为JSON,还是XML或其他东西? 尝试返回ResponseEntity,因为您可以直接控制内容类型。

 protected ResponseEntity createResponseEntity(ValidationErrorResponse restApiError) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); // assuming your ValidationErrorResponse object has an http code stored in it HttpStatus responseStatus = HttpStatus.valueOf(restApiError.getHttpStatus()); ResponseEntity result = new ResponseEntity<>(restApiError, headers, responseStatus); return result; } 

我在我的应用程序中使用类似的东西,我也有一堆RuntimeExceptions,我可以抛出包含wihtin它们足够的信息,能够生成正确的错误响应。