web-dev-qa-db-ja.com

Java構成でWeb.xmlなしのSpring MVCで404ページが見つからないという例外を処理する方法

Spring MVC Webアプリで404ページが見つかりませんという例外を処理したいのですが、_SPRING 4.2.5.RELEASE_を使用しています。このトピックに関するいくつかの質問を読んだことがありましたが、同様の質問で別のSpringを使用していますJava設定。

すべての例外を含むグローバル例外ハンドラーコントローラークラスがあります。このクラスは正常に動作しますが、404ページが見つからないという例外を処理できません。

これは私がチュートリアルに従っているアプローチです

1)ResourceNotFoundExceptionから拡張されたRuntimeExceptionという名前のクラスを作成し、このアノテーションをクラス定義@ResponseStatus(HttpStatus.NOT_FOUND)の上に置きました

このような:

_@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException { 

}
_

2)このメソッドを例外のコントローラークラスに作成しました

_@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handleResourceNotFoundException() {

    return "notFoundJSPPage";
}
_

しかし、まだ存在しないURLを入力すると、「URIを含むHTTPリクエストのマッピングが見つかりません」というエラーが表示されます

私が読んだ質問では、Dispatcherのオプションをtrueに設定する必要があると述べていますが、私の設定は他の質問とは異なり、_Web.xml_がないため、それを適用できませんでした。

これが私のConfig.Javaです

_@EnableWebMvc
@Configuration
@ComponentScan({"config", "controllers"})
public class ConfigMVC extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/");
    }

    @Bean
    public UrlBasedViewResolver setupViewResolver() {
        UrlBasedViewResolver resolver = new UrlBasedViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }

}
_

これが私のWebInitializerです

_public class WebInicializar implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(ConfigMVC.class);
        ctx.setServletContext(servletContext);
        Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);


    }
}
_

これが私のグローバル例外ハンドラコントローラです

_@ControllerAdvice
public class GlobalExceptionHandlerController {


    @ExceptionHandler(value = NullPointerException.class)
    public String handleNullPointerException(Exception e) {

        System.out.println("A null pointer exception ocurred " + e);

        return "nullpointerExceptionPage";
    }


    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(value = Exception.class)
    public String handleAllException(Exception e) {

        System.out.println("A unknow Exception Ocurred: " + e);

        return "unknowExceptionPage";
    }


    @ExceptionHandler(ResourceNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public String handleResourceNotFoundException() {

        return "notFoundJSPPage";
    }

}
_

そして、ランタイム例外を拡張する私が作成したクラス

_@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException{

}
_
7
StackQuestion

この行を_WebApplicationInitializer.class_のonStartupメソッドに入れることで問題を解決しました

これは私が追加する行ですservlet.setInitParameter("throwExceptionIfNoHandlerFound", "true");

これは、追加した新しい行を含む完全なメソッドの外観です。

_@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
    ctx.register(ConfigMVC.class);
    ctx.setServletContext(servletContext);
    Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
    servlet.addMapping("/");
    servlet.setLoadOnStartup(1);
    servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}
_

次に、このコントローラメソッドを_GlobalExceptionHandlerController.class_に作成しました

_@ExceptionHandler(NoHandlerFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
public String handle(NoHandlerFoundException ex) {

  return "my404Page";
}
_

それで私の問題は解決しました。handleResourceNotFoundExceptionコントローラーメソッドを_GlobalExceptionHandlerController.class_から削除しました。これは不要だったためです。また、作成した例外クラス_ResourceNotFoundException.class_も削除しました。

8
StackQuestion

AbstractAnnotationConfigDispatcherServletInitializerを拡張して、このメソッドをオーバーライドすることもできます。

@Override
protected DispatcherServlet createDispatcherServlet(WebApplicationContext servletAppContext) {
    final DispatcherServlet dispatcherServlet = (DispatcherServlet) super.createDispatcherServlet(servletAppContext);
    dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
    return dispatcherServlet;
}

またはこれ:

@Override
public void customizeRegistration(ServletRegistration.Dynamic registration) {
    registration.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}

そして最後にControlerAdviceでこれを使用してください:

@ExceptionHandler(NoHandlerFoundException.class)
public String error404(Exception ex) {

    return new ModelAndView("404");
}
2
zygimantus

コントローラーに次のコードを追加し、404ページを作成します

@GetMapping("/*")
public String handle() {
    return "404";
}
0
Deepu

Zygimantusによる回答が何らかの理由で機能しないことがわかったため、同じ問題がある場合は、「@ ExceptionHandler」を宣言する代わりに、これらの1つを「@Configuration」クラスに追加してください。私は自分のWebMvcConfigurerAdapterに私のものを入れました

@Bean
  public HandlerExceptionResolver handlerExceptionResolver(){
      HandlerExceptionResolver myResolver = new HandlerExceptionResolver(){

        @Override
        public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) {
              //return your 404 page
            ModelAndView mav = new ModelAndView("404page");
            mav.addObject("error", exception);
            return mav;
        }
      };
      return myResolver;
  }

ただし、残りのzygimantusも必ず確認してください。

dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
0
cgull