9

バックグラウンド

エラーメッセージクラスがあります:

@XmlRootElement
public class ErrorMessage {
    private String message;

    public ErrorMessage() {
    }

    public ErrorMessage(String message) {
        this.message = message;
    }

    public String getError() {
        return message;
    }

    public void setError(String message) {
        this.message = message;
    }
}

このクラスは、Spring MVC REST コントローラーの @ExceptionHandler への戻り値として割り当てられています。

@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
ErrorMessage handleException(RuntimeException e) {
    return new ErrorMessage("something went wrong");
}

クライアントが をヘッダーとしてRuntimeExceptionリクエストを発行した後にトリガーするたびに、正しいステータス コードと一致する JSON 本文を含むレスポンスを受け取ります。application/jsonAccept

{"error":"something went wrong"}

Acceptまたは、ヘッダーがapplication/xml次の場合、XML 本文が受信されます。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<errorMessage><error>something went wrong</error></errorMessage>

問題

ここで、代わりにHandlerExceptionResolverを実装してこのソリューションを生成したいと思います。これにより、すべてのコントローラーにコピー/貼り付けする必要がなくなり@ExceptionHandlerます (または、他のコントローラーが拡張できる共通の「親コントローラー」を作成します)。

ただし、AbstractHandlerExceptionResolver.doResolveException()ModelAndViewメソッドは適切ではなくa を返すErrorMessageため、次のことを試しました。

public class RuntimeExceptionHandlerExceptionResolver extends AbstractHandlerExceptionResolver {

    @Override
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        if (ex instanceof RuntimeException) {
            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
            ModelAndView mav = new ModelAndView();
            mav.addObject("error", "something went wrong");
            return mav;
        }
        return null;
    }
}

mav.addObject()デバッグすると、メソッドが呼び出されていることがわかります。クライアント側の応答には予期されたステータス コードがありますが、コンテンツ タイプは、元の要求のヘッダーでtext/html指定された JSON または XLM コンテンツではなく、本文に html が含まれています。Accept

(ちなみに、上記の例の実際の例外、応答コード、およびテキスト メッセージは重要ではありません。これらは単純な例にすぎません。)

春のバージョン: 3.1.1.RELEASE

4

2 に答える 2

4

@ExceptionHandlerコンテンツ ネゴシエーションを使用させるには、メッセージ コンバータで提供する必要がAnnotationMethodHandlerExceptionResolverあるメソッドがあります。たとえば、次のようになります。setMessageConverters()

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
    <property name="messageConverters">
        <list>
            <ref bean="xmlConverter"/>
            <ref bean="jsonConverter"/>
        </list>
    </property>
</bean>

ただし、カスタム メソッドを使用しているため、おそらくこの機能を自分で実装する必要があります。最も簡単な方法は、おそらくソース、具体的にはメソッドCtrl-C Ctrl-Vから取得することです。AnnotationMethodHandlerExceptionResolverhandleResponseBody()

于 2012-06-04T20:14:05.287 に答える
4

私はこの問題を調査するのに時間を費やし、問題の解決策を提示するブログ投稿を書きました。

更新: Spring 3.2 を使用している場合は、@ControllerAdviceアノテーションを利用できます。詳細については、私の2 番目のブログ投稿を参照してください。

于 2012-09-23T21:07:58.337 に答える