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{
}
_
この行を_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
_も削除しました。
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");
}
コントローラーに次のコードを追加し、404ページを作成します
@GetMapping("/*")
public String handle() {
return "404";
}
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);