web-dev-qa-db-ja.com

Spring 3-NoSuchRequestHandlingMethodExceptionのExceptionHandlerを作成する

Spring 3を使用して、"no page found(404)"リクエストを処理するExceptionHandlerアノテーションを使用して例外ハンドラーを作成します。これを行うために次のコードを使用しています。しかし、存在しないURLをポイントすると、Springによって定義されたデフォルトの例外ハンドラーが呼び出されます。

NoSuchRequestHandlingMethodException例外を処理している可能性があります。ある場合、どの例外を登録する必要がありますか?

次のコードを見て、私が間違っていることを確認してください。

注:@ ExceptionHandlerの例外をNullPointerExceptionに変更し、RequestMappingを作成してnullポインターをスローすると、機能します。

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

    import org.Apache.commons.logging.Log;
    import org.Apache.commons.logging.LogFactory;
    import org.springframework.web.servlet.ModelAndView;

    @Controller
    public class GeneralHandler {
      private final Log logger = LogFactory.getLog(getClass());

      @ExceptionHandler(NoSuchRequestHandlingMethodException.class)
      public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
        ModelAndView mav = new ModelAndView();
        logger.error("Exception found: " + ex);
        return mav;
      }
    }
28
sgsweb

@ExceptionHandler注釈付きメソッドは、同じクラスの@RequestMappingメソッドが例外をスローしたときに呼び出されます。そのため、NullPointerExceptionをスローするマッピングを追加すると、マッピングされたメソッドと例外ハンドラーが同じクラス内にあったため、うまくいきました。

マッピングが見つからない場合、SpringはNoSuchRequestHandlingMethodException@ExceptionHandlerに関連付ける方法がありません。これは、リクエストをハンドラーメソッドに一致させることができないためです。これはドキュメントでは明示的に言及されていませんが、私が観察した動作です。

この例外を特別に処理する場合は、より特化した@ExceptionHandler手法ではなく、より一般的な HandlerExceptionResolverアプローチ を使用する必要があります。

41
skaffman

Spring 3.2では、 @ ContollerAdvice を使用して、次のようにすべてのコントローラーにExceptionHandlerを設定できます。

@ControllerAdvice
public class GeneralHandler {

   @ExceptionHandler
   public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
        ModelAndView mav = new ModelAndView();
        ...
        return mav;
   }
}

さらに注釈を追加して、シリアル化されたjsonを返すこともできます

@ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public RestError resolveBindingException ( MethodArgumentNotValidException methodArgumentNotValidException, Locale locale )
    {
        BindingResult bindingResult = methodArgumentNotValidException.getBindingResult();
        return getRestError(bindingResult, locale);
    }
16
Janning

あなたは this アプローチで行くことができます、それは素晴らしいアイデアであり、機能します、特定のHandlerでのみ例外をスローする必要があるため、@ ExceptionHandlerは見た目ほど役に立ちません。

2
lisak