1

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

在 Spring 3.0.x 中,有一个已确认的bug已解决,导致它无法正常工作。我使用的是 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<ValidationError> errs = new LinkedList<ValidationError>();
    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);
}

有任何想法吗?

4

3 回答 3

1

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

如果您使用的是 Spring 3.1.2,@ExceptionHandler 和 @ResponseBody 确实可以工作。

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

于 2012-10-24T00:48:01.220 回答
1

当我需要为以“/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);
    }
}
于 2015-05-19T20:23:50.537 回答
0

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

protected ResponseEntity<ValidationErrorResponse> 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<RestApiError> result = new ResponseEntity<>(restApiError, headers, responseStatus);
        return result;
    }

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

于 2012-10-22T16:11:58.743 回答