java - 如何在带有java配置且没有Web.xml的Spring MVC中处理404页面未找到异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36000137/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 17:21:14  来源:igfitidea点击:

How to handle 404 page not found exception in Spring MVC with java configuration and no Web.xml

javaspringspring-mvcexceptionannotations

提问by StackQuestion

I want to handle 404 page not found exception in my Spring MVC web app, I'm using SPRING 4.2.5.RELEASE, I had read several question regarding this topic but the similar questions are using a different spring java configuration.

我想在我的 Spring MVC web 应用程序中处理 404 页面未找到异常,我正在使用SPRING 4.2.5.RELEASE,我已经阅读了几个关于这个主题的问题,但类似的问题使用了不同的 spring java 配置。

I have a Global Exception Handler Controller class that have all my Exceptions, this class works fine but I can't handle a 404 page not found exception.

我有一个全局异常处理程序控制器类,其中包含我所有的异常,这个类工作正常,但我无法处理 404 页面未找到异常。

This is the approach that I take following a tutorial

这是我按照教程采取的方法

1) I created a class named ResourceNotFoundExceptionthat extends from RuntimeExceptionand I putted this annotation over the class definition @ResponseStatus(HttpStatus.NOT_FOUND)

1)我创建了一个名为ResourceNotFoundException扩展的类,RuntimeException并将此注释放在类定义上@ResponseStatus(HttpStatus.NOT_FOUND)

like this:

像这样:

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

}

2) I created this method in my exception's controller class

2)我在异常的控制器类中创建了这个方法

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

    return "notFoundJSPPage";
}

But still when I put a URL that doesn't exist I get this error "No mapping found for HTTP request with URI"

但是当我输入一个不存在的 URL 时,我仍然收到此错误“未找到带有 URI 的 HTTP 请求的映射”

The questions that I had read said that I need to enable to true an option for the Dispatcher but since my configuration it's different from the other questions and I don't have a Web.xmlI couldn't apply that.

我读过的问题说我需要为 Dispatcher 启用一个选项,但由于我的配置与其他问题不同,我没有一个Web.xml我无法应用它。

Here it's my Config.java

这是我的 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;
    }

}

Here is my WebInitializer

这是我的 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);


    }
}

Here is my Global Exception Handler Controller

这是我的全局异常处理程序控制器

@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";
    }

}

And the class I created that extends Runtime Exception

我创建的类扩展了运行时异常

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

}

采纳答案by StackQuestion

I solved the problem by putting this line in my onStartupmethod in the WebApplicationInitializer.class

我通过将这一行放在我的onStartup方法中解决了这个问题WebApplicationInitializer.class

this it's the line I add servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true");

这是我添加的行 servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true");

this is how it looks the complete method with the new line I added

这是我添加的新行的完整方法的外观

@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");
}

Then I created this controller method in my GlobalExceptionHandlerController.class

然后我在我的 GlobalExceptionHandlerController.class

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

  return "my404Page";
}

and that solved my problem I deleted the handleResourceNotFoundExceptioncontroller method in my GlobalExceptionHandlerController.classsince it wasn't necessary and also I deleted the exception class ResourceNotFoundException.classthat I created

这解决了我的问题我删除了我的handleResourceNotFoundException控制器方法,GlobalExceptionHandlerController.class因为它不是必需的,并且我删除了ResourceNotFoundException.class我创建的异常类

回答by zygimantus

You can also extend AbstractAnnotationConfigDispatcherServletInitializerand override this method:

您还可以扩展AbstractAnnotationConfigDispatcherServletInitializer和覆盖此方法:

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

OR this one:

或者这个:

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

And finally in your ControlerAdviceuse this:

最后在你ControlerAdvice使用这个:

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

    return new ModelAndView("404");
}

回答by cgull

I found that the answer by zygimantus didnt work for some reason, so if you also have the same problem , then instead of declaring an "@ExceptionHandler", add one of these to a "@Configuration" class instead. I put mine in my WebMvcConfigurerAdapter

我发现 zygimantus 的答案由于某种原因不起作用,所以如果你也有同样的问题,那么不要声明“@ExceptionHandler”,而是将其中一个添加到“@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;
  }

But make sure you also follow the rest of zygimantus ie

但请确保您也遵循 zygimantus 的其余部分,即

dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);

回答by Deepu

Add following code in any controller and create a 404 page

在任何控制器中添加以下代码并创建一个 404 页面

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