1

@ResponseBody を使用して Spring Web MVC @ExceptionHandler を実装して、検証エラーを含むオブジェクトを返そうとしています。(戦略 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<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

「/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 に答える
1

あなたがこれを読んでいるなら、おそらく私がこれをどのように機能させたのかについて疑問を持っているでしょう. 短い答えは、私にはわからないということです。コードを元に戻し、ここから再実装 (実際にはコントローラー ビットをコピー アンド ペースト) したところ、突然動作し始めました。

Spring 3.1.2 を使用している場合、@ExceptionHandler と @ResponseBody は機能します。

これが最初に機能しなかった理由についての私の暫定的な説明は、おそらくユーザー エラーか、使用していた (非常に複雑で、このアプリケーションは大規模です) 展開スクリプトのエラーであるというものでした。

于 2012-10-24T00:48:01.220 に答える
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 に答える