9

SpringMVCとjacksonがあります。間違ったリクエストを開始すると、Jacksonマッピングが失敗し、UnrecognizedPropertyExceptionスローされます。この例外を使用して処理したい

@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
  ...
}

ただし、Springはこの例外をラップするHttpMessageConversionExceptionため、上記のコードは機能しません。SpringでJackson固有の(または一般的にライブラリ固有の)例外を処理することは可能ですか?

4

3 に答える 3

7

残念ながら、UnrecognizedPropertyExceptionはのサブタイプですIOException。(例外が発生する場所だと思います)を処理するは、(要求入力ストリームの失敗として解釈する)ための特別な処理を持ちRequestResponseBodyMethodProcessor、それを。でラップします。さらに、インターフェイスは、の間に変換エラーが発生した場合にスローするように指定されています。@RequestBodyIOExceptionHttpMessageNotReadableExceptionHttpMessageConverterHttpMessageNotReadableExceptionread

何があってもそれに対処する必要があります(代わりにジャクソンがチェックされていない例外をスローした場合は、状況が異なっていた可能性があります)。

幸い、4.3以降、Spring MVCExceptionHandlerMethodResolver(処理する@ExceptionHandlercauseは例外のラップを解除できます(SPR-14291を参照)。そのため、の継承階層に例外のハンドラーがないと仮定するとHttpMessageNotReadableException、ハンドラーメソッドは

@ExceptionHandler
public String handle(UnrecognizedPropertyException e) {
    ...
}

例外を処理するために使用されます。これは、Spring MVCがを処理できるハンドラーメソッドをHttpMessageNotReadableException探し、ネストされた例外をでラップ解除してThrowable#getCause、ルックアップを再試行した後に発生します。


4.3より前では、またはの継承階層に例外タイプのハンドラーがある場合はHttpMessageNotReadableException、原因を自分で抽出した後、いつでも委任できます。

@ExceptionHandler
public String handle(HttpMessageConversionException e) throws Throwable {
    Throwable cause = e.getCause();
    if (cause instanceof UnrecognizedPropertyException) {
        handle((UnrecognizedPropertyException) cause);
    }
    ...
}

public String handle(UnrecognizedPropertyException e) {
    ...
}
于 2013-03-20T16:50:46.540 に答える
0

私はそれをこのようにします:

/**
 * Global exception handler for unhandled errors.
 * @author Varun Achar
 * @since 2.0
 * @version 1.0
 *
 */
public class Http500ExceptionResolver extends SimpleMappingExceptionResolver
{
    @Inject
    private ViewResolver resolver;

    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    {
        ModelAndView mv = new ModelAndView();
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        if(CommonUtil.isAjax(request))
        {
            MappingJackson2JsonView view = new MappingJackson2JsonView();
            view.setObjectMapper(JsonUtil.getObjectMapper());
            mv.addObject("responseMessage", "We had some problems while serving your request. We are looking into it");
            mv.addObject("responseCode", GenericResponse.ERROR.code());
            mv.addObject("success", false);
            mv.setView(view);
        }
        else
        {
            mv.setViewName(resolver.getView(ViewConstants.ERROR_PAGE));
        }
        return mv;
    }
}

そして私のサーブレットコンテキストでは:

   <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
        <property name="order" value="0" />
    </bean>
    <bean id="securityExceptionResolver"
        class="com.trelta.commons.utils.security.SecurityExceptionResolver">
        <property name="order" value="1"></property>
        <property name="exceptionMappings">
            <map>
                <entry key="org.springframework.security.access.AccessDeniedException"
                    value="/common/accessDenied"></entry>
                <entry key="org.springframework.security.core.AuthenticationException"
                    value="/common/authenticationFailure"></entry>
            </map>
        </property>
    </bean>
    <bean id="http500ExceptionResolver"
            class="com.trelta.commons.utils.security.Http500ExceptionResolver">
            <property name="order" value="3" />
    </bean>

Springは例外リゾルバーをこの順序で循環するため、順序フィールドは重要です。この種の例外マッピングを自分で定義することもできます。

SimpleMappingExceptionResolverについては、このブログ投稿とjavadocを確認してください

于 2013-03-20T21:16:21.343 に答える
0

org.apache.commons.lang.exception.ExceptionUtils..を使用しています。

private myMethod (Throwable t) {

    if (ExceptionUtils.getRootCause(t) instanceof MyException) ...
}
于 2019-03-11T15:09:04.517 に答える