Je gère les exceptions à l'aide de @ControllerAdvice, j'ai sur @ControllerAdvice pour mes contrôleurs de repos et un pour les contrôleurs de repos, ils sélectionnent des exceptions pour Exception.class mais ils ne sont pas choisir NoHandlerFoundException.class.Spring L'exception @ControllerAdvice Handler ne sélectionne pas NoHandlerFoundException
Nous utilisons Spring 4.3.7.RELEASE, Java Config, Apache 8.5.12.
est inférieure à la classe MyWebInitializer
public class MyWebInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
servletContext.addListener(new RequestContextListener());
servletContext.addListener(new SpringSessionListener());
ServletRegistration.Dynamic dispatcher1 =
servletContext.addServlet("blackwellsjspservlet", new JspServlet());
dispatcher1.setLoadOnStartup(3);
dispatcher1.addMapping("*.do");
}
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SpringRootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { SpringWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected String getServletName() {
return "blackwellsmvcdispatcherservlet";
}
//Added to allow customised NoHandlerFoundPage
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true
if(!done) throw new RuntimeException();
}
//Added to register a default profile
@Override
protected WebApplicationContext createServletApplicationContext() {
WebApplicationContext context = (WebApplicationContext) super.createServletApplicationContext();
((ConfigurableEnvironment) context.getEnvironment()).setDefaultProfiles("production");
return context;
}
}
Mon SpringWebConfig est:
@EnableWebMvc
@Configuration
public class SpringWebConfig extends WebMvcConfigurerAdapter {
@Autowired
private ServletContext servletContext;
@Autowired
Environment env;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public InternalResourceViewResolver jspViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/");
viewResolver.setViewNames("*.jsp");
return viewResolver;
}
@Bean
public Loader<?> templateLoader(){
return new ServletLoader(servletContext);
}
@Bean
public CustomSpringExtension springExtension() {
return new CustomSpringExtension();
}
@Bean
public PebbleEngine pebbleEngine() {
return new PebbleEngine.Builder()
.loader(this.templateLoader()).cacheActive(false)
.extension(springExtension())
.build();
}
@Bean
public ViewResolver pebbleViewResolver() {
PebbleViewResolver viewResolver = new PebbleViewResolver();
viewResolver.setPrefix("/WEB-INF/patternLab/");
viewResolver.setPebbleEngine(pebbleEngine());
viewResolver.setOrder(Ordered.LOWEST_PRECEDENCE - 5);
viewResolver.setViewNames("*.html");
return viewResolver;
}
/**
* Bean for ResourceMessageBundle
* basename and folder resources/locale/messages. i.g. messages_en_GB.properties,messages_en_US.properties
* @author Henrique Droog
* @return
*/
@Bean
public MessageSource messageSource(){
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:locale/messages");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
/**
* Bean for LocalResolver
* set en as a default locale
* @author Henrique Droog
* @date 09.03.2017
* @return
*/
@Bean
public LocaleResolver localeResolver(){
CookieLocaleResolver resolver = new CookieLocaleResolver();
resolver.setDefaultLocale(new Locale("en"));
resolver.setCookieName("myLocaleCookie");
resolver.setCookieMaxAge(4800);
return resolver;
}
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor(){
return new MethodValidationPostProcessor();
}
@Profile({"production-api","dev-api"})
@ComponentScan(basePackages = { "uk.co.blackwells.controllers", "uk.co.blackwells.rest.controller"})
public static class ProductionAPIWebConfig {
}
@Profile({"production","dev","default"})
@ComponentScan(basePackages = { "uk.co.blackwells.controllers","uk.co.blackwells.rest.controller"})
public static class ProductionWebConfig {
}
@Profile({"test"})
@ComponentScan(basePackages = { "uk.co.blackwells.controllers","uk.co.blackwells.rest.controller"})
public static class TestWebConfig {
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(sessionInterceptor()).addPathPatterns("/**").excludePathPatterns("/api/**", "/restful/**");
LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
interceptor.setParamName("mylocale");
registry.addInterceptor(interceptor);
}
@Bean
public SessionInterceptor sessionInterceptor() {
return new SessionInterceptor();
}
@Bean
public Validator validatorFactory() {
return new LocalValidatorFactoryBean();
}
}
Mes conseils des contrôleurs pour les contrôleurs non de repos:
@ControllerAdvice(annotations=Controller.class)
public class GlobalDefaultExceptionHandlerController {
private final Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandlerController.class);
ErrorList errorList;
/**
* This init binder register a custom editor to trim all fields coming
* from html
* @param binder
*/
@InitBinder
public void initBinder (WebDataBinder binder)
{
StringTrimmerEditor stringtrimmer = new StringTrimmerEditor(true);
binder.registerCustomEditor(String.class, stringtrimmer);
}
@ExceptionHandler(NoHandlerFoundException.class)
public ModelAndView handleNotFoundException(HttpServletRequest req, NoHandlerFoundException ex) {
ErrorMessage erMsg = new ErrorMessage();
erMsg.setError(ex.getMessage());
erMsg.setStackTrace(stackTrace);
erMsg.setException(ex);
ModelAndView model = new ModelAndView();
model.addObject("errorMessageObject", erMsg);
model.setViewName("pages/error-404.html");
return model;
}
@ExceptionHandler(Exception.class)
public ModelAndView handleAllException(HttpServletRequest req, Exception ex) throws Exception {
// Rethrow annotated exceptions or they will be processed here instead.
if (AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class) != null)
throw ex;
ErrorMessage erMsg = new ErrorMessage();
erMsg.setError(exceptionCode);
erMsg.setStackTrace(stackTrace);
erMsg.setException(ex);
ModelAndView model = new ModelAndView();
model.addObject("errorMessageObject", erMsg);
model.addObject("errMsg", ex.getMessage());
model.addObject("exceptionCode", exceptionCode);
model.setViewName("pages/error-500.html");
return model;
}
@RequestMapping(value = {"/SessionError"}, method = RequestMethod.GET)
public String sessionError() {
return "pages/error-500.html";
}
}
Pour les contrôleurs de repos:
@RestControllerAdvice(annotations=RestController.class)
public class ApiExceptionHandlerController {
private final Logger logger = LoggerFactory.getLogger(ApiExceptionHandlerController.class);
@ExceptionHandler(Exception.class)
public ResponseEntity<Object> handleException(HttpServletRequest req, Exception ex){
logger.error("API Exception: {}", ex.getMessage(), ex);
logger.error("Path:{}, IP:{}", req.getServletPath(), req.getRemoteAddr());
ApiError apiError =
new ApiError(HttpStatus.INTERNAL_SERVER_ERROR, "Internal server error", ex.getMessage());
return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<Object> handleNotFoundException(HttpServletRequest req, Exception ex){
logger.error("API NoHandlerFoundException: {}", ex.getMessage(), ex);
logger.error("Path:{}, IP:{}", req.getServletPath(), req.getRemoteAddr());
ex.printStackTrace();
ApiError apiError =
new ApiError(HttpStatus.NOT_FOUND, ex.getMessage(), ex.getMessage());
return new ResponseEntity<Object>(apiError, new HttpHeaders(), apiError.getStatus());
}
}
Les deux conseils du contrôleur sélectionnaient NoHandlerFoundException jusqu'à il y a quelque temps. J'ai jeté un oeil dans les changements d'historique pour ces fichiers mais ils n'ont pas été changés depuis un moment. Je pense que peut-être cette partie du code
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
boolean done = registration.setInitParameter("throwExceptionIfNoHandlerFound", "true"); // -> true
if(!done) throw new RuntimeException();
}
est en cours pour une autre surchargée code, mais je ne peux pas trouver tout ce qui concerne ce sujet.
Merci Dave, malheureusement, je ne suis pas avec Spring Boot. J'ai également mis throwExceptionIfNoHandlerFound comme true dans l'initialiseur web qui étend AbstractAnnotationConfigDispatcherServletInitializer. Quoi qu'il en soit, je vais penser si je peux essayer en utilisant certaines propriétés à la place de l'initialiseur web. –