(SOLUTION am Ende der Frage veröffentlicht)HOWTO behandeln global 404 Ausnahmen mit Spring MVC konfiguriert Java-basierte Anmerkungen
Ich bin ein Spring 4 MVC-app zu bauen. Und es ist vollständig mit Java-Annotationen konfiguriert. Es gibt keine web.xml
. Die App unter Verwendung Instanz von AbstractAnnotationConfigDispatcherServletInitializer
und WebMvcConfigurerAdapter
wie so konfiguriert ist,
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.example.*"})
@EnableTransactionManagement
@PropertySource("/WEB-INF/properties/application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
...
}
und
public class WebAppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
...
}
Ich versuche jetzt, einen globalen/Catch-Alle Exception-Handler hinzufügen für 404 Seiten, dh HttpStatus.NOT_FOUND
aber keine Erfolg. Im Folgenden sind einige der Möglichkeiten, die ich versucht habe.
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;
@ControllerAdvice
public class GlobalExceptionHandlerController {
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
ModelAndView mav = new ModelAndView();
return mav;
}
@ExceptionHandler
@ResponseStatus(HttpStatus.NOT_FOUND)
public ModelAndView handleExceptiond (NoHandlerFoundException ex) {
ModelAndView mav = new ModelAndView();
return mav;
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoHandlerFoundException.class)
public void handleConflict() {
}
@ResponseStatus(HttpStatus.NOT_FOUND)
@ExceptionHandler(NoSuchRequestHandlingMethodException.class)
public void handlesdConflict() {
}
}
Keine dieser Methoden wird ausgeführt. Ich weiß nicht, wie ich damit umgehen soll. Ich möchte nicht web.xml
verwenden, weil ich dann nur dafür eine erstellen müsste.
LÖSUNG Ich tat was @Sotirios mentioned here. Hier ist mein Teil WebAppInitializer
Code, der den Dispatcher richtig einstellen wird.
public class WebAppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
...
@Override
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = super.getServletName();
Assert.hasLength(servletName, "getServletName() may not return empty or null");
WebApplicationContext servletAppContext = super.createServletApplicationContext();
Assert.notNull(servletAppContext,
"createServletApplicationContext() did not return an application " +
"context for servlet [" + servletName + "]");
DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
//>>> START: My custom code, rest is exqact copy of the super class
dispatcherServlet.setThrowExceptionIfNoHandlerFound(true);
//>>> END
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
Assert.notNull(registration,
"Failed to register servlet with name '" + servletName + "'." +
"Check if there is another servlet registered under the same name.");
registration.setLoadOnStartup(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
Filter[] filters = getServletFilters();
if (!ObjectUtils.isEmpty(filters)) {
for (Filter filter : filters) {
super.registerServletFilter(servletContext, filter);
}
}
super.customizeRegistration(registration);
}
...
}
Obwohl ich bin nicht besonders glücklich mit dieser Lösung, weil mein einziger benutzerdefinierter Code ist 1 Zeile & Rest direkt aus Super-Klasse kopiert. Ich wünschte, es gäbe einen schöneren Weg dazu.
fügte ich weiß nicht, warum sie es nicht taten mache das 'DispatcherServlet' durch eine' geschützte' Methode sichtbar, aber die benutzerdefinierte Lösung scheint gut zu sein. –
Warum überschreiben Sie einfach nur createDispatcherServlet – Ysak