/** * Returns a {@link HandlerExceptionResolverComposite} containing a list of exception * resolvers obtained either through {@link #configureHandlerExceptionResolvers} or * through {@link #addDefaultHandlerExceptionResolvers}. * <p><strong>Note:</strong> This method cannot be made final due to CGLIB constraints. * Rather than overriding it, consider overriding {@link #configureHandlerExceptionResolvers} * which allows for providing a list of resolvers. */ @Bean public HandlerExceptionResolver handlerExceptionResolver() { List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>(); configureHandlerExceptionResolvers(exceptionResolvers); if (exceptionResolvers.isEmpty()) { addDefaultHandlerExceptionResolvers(exceptionResolvers); } extendHandlerExceptionResolvers(exceptionResolvers); HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite(); composite.setOrder(0); composite.setExceptionResolvers(exceptionResolvers); return composite; }
@Test public void exceptionResolvers() throws Exception { List<HandlerExceptionResolver> resolvers = ((HandlerExceptionResolverComposite) this.config.handlerExceptionResolver()).getExceptionResolvers(); assertEquals(2, resolvers.size()); assertEquals(ResponseStatusExceptionResolver.class, resolvers.get(0).getClass()); assertEquals(SimpleMappingExceptionResolver.class, resolvers.get(1).getClass()); }
/** * Returns a {@link HandlerExceptionResolverComposite} containing a list of exception * resolvers obtained either through {@link #configureHandlerExceptionResolvers} or * through {@link #addDefaultHandlerExceptionResolvers}. * <p><strong>Note:</strong> This method cannot be made final due to CGLIB constraints. * Rather than overriding it, consider overriding {@link #configureHandlerExceptionResolvers} * which allows for providing a list of resolvers. */ @Bean public HandlerExceptionResolver handlerExceptionResolver() { List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<HandlerExceptionResolver>(); configureHandlerExceptionResolvers(exceptionResolvers); if (exceptionResolvers.isEmpty()) { addDefaultHandlerExceptionResolvers(exceptionResolvers); } extendHandlerExceptionResolvers(exceptionResolvers); HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite(); composite.setOrder(0); composite.setExceptionResolvers(exceptionResolvers); return composite; }
@Test @SuppressWarnings("unchecked") public void handlerExceptionResolver() throws Exception { ApplicationContext context = initContext(WebConfig.class); HandlerExceptionResolverComposite compositeResolver = context.getBean("handlerExceptionResolver", HandlerExceptionResolverComposite.class); assertEquals(0, compositeResolver.getOrder()); List<HandlerExceptionResolver> expectedResolvers = compositeResolver.getExceptionResolvers(); assertEquals(ExceptionHandlerExceptionResolver.class, expectedResolvers.get(0).getClass()); assertEquals(ResponseStatusExceptionResolver.class, expectedResolvers.get(1).getClass()); assertEquals(DefaultHandlerExceptionResolver.class, expectedResolvers.get(2).getClass()); ExceptionHandlerExceptionResolver eher = (ExceptionHandlerExceptionResolver) expectedResolvers.get(0); assertNotNull(eher.getApplicationContext()); DirectFieldAccessor fieldAccessor = new DirectFieldAccessor(eher); List<Object> interceptors = (List<Object>) fieldAccessor.getPropertyValue("responseBodyAdvice"); assertEquals(1, interceptors.size()); assertEquals(JsonViewResponseBodyAdvice.class, interceptors.get(0).getClass()); LocaleContextHolder.setLocale(Locale.ENGLISH); try { ResponseStatusExceptionResolver rser = (ResponseStatusExceptionResolver) expectedResolvers.get(1); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/"); MockHttpServletResponse response = new MockHttpServletResponse(); rser.resolveException(request, response, context.getBean(TestController.class), new UserAlreadyExistsException()); assertEquals("User already exists!", response.getErrorMessage()); } finally { LocaleContextHolder.resetLocaleContext(); } }
/** * Returns a {@link HandlerExceptionResolverComposite} containing a list of exception * resolvers obtained either through {@link #configureHandlerExceptionResolvers} or * through {@link #addDefaultHandlerExceptionResolvers}. * <p><strong>Note:</strong> This method cannot be made final due to CGLIB constraints. * Rather than overriding it, consider overriding {@link #configureHandlerExceptionResolvers} * which allows for providing a list of resolvers. */ @Bean public HandlerExceptionResolver handlerExceptionResolver() { List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>(); configureHandlerExceptionResolvers(exceptionResolvers); if (exceptionResolvers.isEmpty()) { addDefaultHandlerExceptionResolvers(exceptionResolvers); } extendHandlerExceptionResolvers(exceptionResolvers); HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite(); composite.setOrder(0); composite.setExceptionResolvers(exceptionResolvers); return composite; }
@Test public void configureExceptionResolvers() throws Exception { List<WebMvcConfigurer> configurers = new ArrayList<>(); configurers.add(new WebMvcConfigurer() { @Override public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { exceptionResolvers.add(new DefaultHandlerExceptionResolver()); } }); delegatingConfig.setConfigurers(configurers); HandlerExceptionResolverComposite composite = (HandlerExceptionResolverComposite) delegatingConfig.handlerExceptionResolver(); assertEquals("Only one custom converter is expected", 1, composite.getExceptionResolvers().size()); }
@Test public void customArgumentResolvers() { ApplicationContext context = initContext(CustomArgumentResolverConfig.class); RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class); HandlerExceptionResolverComposite composite = context.getBean(HandlerExceptionResolverComposite.class); assertNotNull(adapter); assertEquals(1, adapter.getCustomArgumentResolvers().size()); assertEquals(TestArgumentResolver.class, adapter.getCustomArgumentResolvers().get(0).getClass()); assertEquals(1, adapter.getCustomReturnValueHandlers().size()); assertEquals(TestReturnValueHandler.class, adapter.getCustomReturnValueHandlers().get(0).getClass()); assertNotNull(composite); assertEquals(3, composite.getExceptionResolvers().size()); assertEquals(ExceptionHandlerExceptionResolver.class, composite.getExceptionResolvers().get(0).getClass()); ExceptionHandlerExceptionResolver resolver = (ExceptionHandlerExceptionResolver) composite.getExceptionResolvers().get(0); assertEquals(1, resolver.getCustomArgumentResolvers().size()); assertEquals(TestArgumentResolver.class, resolver.getCustomArgumentResolvers().get(0).getClass()); assertEquals(1, resolver.getCustomReturnValueHandlers().size()); assertEquals(TestReturnValueHandler.class, resolver.getCustomReturnValueHandlers().get(0).getClass()); }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (!enabled) return bean; // Must return the bean or we lose it! // Display the bean. If it is Ordered, print its order also. Several MVC // classes are chained by Order and it is often useful to see what order // they are configured to run. if (bean instanceof Ordered) { String order = (bean instanceof Ordered) ? String .valueOf(((Ordered) bean).getOrder()) : "unknown"; logger.info(bean.getClass().getName() + " - Order: " + order); } else { logger.info(bean.getClass().getName()); } // Since we are concerned with exception-resolvers, lets print extra // info about this one. It delegates in turn to all the default // resolvers - see "Going Deeper" in the Blog for more details. if (bean instanceof HandlerExceptionResolverComposite) { logger.info(" resolvers: " + ((HandlerExceptionResolverComposite) bean) .getExceptionResolvers()); } // Must return the bean or we lose it! return bean; }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (!enabled) return bean; // Must return the bean or we lose it! // Display the bean. If it is Ordered, print its order also. Several MVC // classes are chained by Order and it is often useful to see what order // they are configured to run. if (bean instanceof Ordered) { String order = (bean instanceof Ordered) ? String .valueOf(((Ordered) bean).getOrder()) : "unknown"; logger.info(bean.getClass().getName() + " - Order: " + order); } else { logger.info(bean.getClass().getName()); } // Since we are concerned with exception-resolvers, lets print extra // info about this one. It delegates in turn to all the default // resolvers - see "Going Deeper" in the Blog for more details. if (bean instanceof HandlerExceptionResolverComposite) { logger.info(" resolvers: " + ((HandlerExceptionResolverComposite) bean) .getExceptionResolvers()); } // Must return the bean or we lose it! return bean; }