webentwicklung-frage-antwort-db.com.de

Behandlung von 404-Seiten, die in Spring MVC mit Java-Konfiguration und ohne Web.xml-Ausnahme nicht gefunden wurden

Ich möchte die 404-Seite behandeln, die in meiner Spring-MVC-Web-App nicht gefunden wurde. Ich verwende SPRING 4.2.5.RELEASE. Ich hatte einige Fragen zu diesem Thema gelesen, aber die ähnlichen Fragen verwenden eine andere Spring-Java-Konfiguration.

Ich habe eine Global Exception Handler Controller-Klasse, die alle meine Exceptions hat. Diese Klasse funktioniert gut, aber ich kann keine 404-Seite behandeln, die keine Ausnahme gefunden hat.

Dies ist der Ansatz, den ich nach einem Tutorial nehme

1) Ich habe eine Klasse mit dem Namen ResourceNotFoundException erstellt, die sich von RuntimeException erstreckt, und diese Anmerkung über die Klassendefinition @ResponseStatus(HttpStatus.NOT_FOUND) eingefügt

so was:

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

}

2) Ich habe diese Methode in der Controller-Klasse meiner Ausnahme erstellt

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

    return "notFoundJSPPage";
}

Wenn ich jedoch eine nicht vorhandene URL eingebe, erhalte ich die Fehlermeldung "Keine Zuordnung für HTTP-Anforderung mit URI gefunden".

Die Fragen, die ich gelesen hatte, besagten, dass ich eine Option für den Dispatcher aktivieren muss, aber da meine Konfiguration sich von den anderen Fragen unterscheidet, habe ich keinen Web.xml, den ich nicht anwenden konnte.

Hier ist meine 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;
    }

}

Hier ist mein 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);


    }
}

Hier ist mein 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";
    }

}

Und die Klasse, die ich erstellt habe und die Laufzeitausnahme erweitert

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

}
7
StackQuestion

Ich habe das Problem gelöst, indem ich diese Zeile in meine onStartup-Methode im WebApplicationInitializer.class eingefügt habe. 

dies ist die Zeile, die ich servlet.setInitParameter("throwExceptionIfNoHandlerFound", "true"); hinzufüge

so sieht die komplette Methode mit der neuen Zeile aus, die ich hinzugefügt habe

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

Dann habe ich diese Controller-Methode in meinem GlobalExceptionHandlerController.class erstellt. 

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

  return "my404Page";
}

und damit wurde mein Problem gelöst. Ich löschte die handleResourceNotFoundException Controller-Methode in meinem GlobalExceptionHandlerController.class, da dies nicht notwendig war. Außerdem löschte ich die von mir erstellte Ausnahmeklasse ResourceNotFoundException.class 

8
StackQuestion

Sie können auch AbstractAnnotationConfigDispatcherServletInitializer erweitern und diese Methode überschreiben:

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

Oder dieses:

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

Und schließlich in Ihrer ControlerAdvice verwenden Sie dies:

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

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

Fügen Sie in einem beliebigen Controller den folgenden Code hinzu und erstellen Sie eine 404-Seite

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

Ich fand heraus, dass die Antwort von zygimantus aus irgendeinem Grund nicht funktionierte. Wenn Sie also dasselbe Problem haben, fügen Sie statt einer "@ExceptionHandler" - Klasse statt dessen eine Klasse "@Configuration" hinzu. Ich habe meinen in meinen WebMvcConfigurerAdapter eingefügt

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

Stellen Sie jedoch sicher, dass Sie auch den Rest von Zygimantus befolgen

dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
0
cgull