SPR-6902 - @ResponseBody does not work with @ExceptionHandler

This commit is contained in:
Arjen Poutsma 2011-01-10 12:26:57 +00:00
parent 4998d061f8
commit 157623b47f
2 changed files with 43 additions and 13 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2010 the original author or authors. * Copyright 2002-2011 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -45,7 +45,10 @@ import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor; import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
import org.springframework.web.servlet.handler.MappedInterceptor; import org.springframework.web.servlet.handler.MappedInterceptor;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter; import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver;
import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping; import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping;
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
/** /**
* {@link BeanDefinitionParser} that parses the {@code annotation-driven} element to configure a Spring MVC web * {@link BeanDefinitionParser} that parses the {@code annotation-driven} element to configure a Spring MVC web
@ -111,11 +114,13 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
bindingDef.getPropertyValues().add("conversionService", conversionService); bindingDef.getPropertyValues().add("conversionService", conversionService);
bindingDef.getPropertyValues().add("validator", validator); bindingDef.getPropertyValues().add("validator", validator);
ManagedList<RootBeanDefinition> messageConverters = getMessageConverters(source);
RootBeanDefinition annAdapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class); RootBeanDefinition annAdapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class);
annAdapterDef.setSource(source); annAdapterDef.setSource(source);
annAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); annAdapterDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
annAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef); annAdapterDef.getPropertyValues().add("webBindingInitializer", bindingDef);
annAdapterDef.getPropertyValues().add("messageConverters", getMessageConverters(source)); annAdapterDef.getPropertyValues().add("messageConverters", messageConverters);
String annAdapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef); String annAdapterName = parserContext.getReaderContext().registerWithGeneratedName(annAdapterDef);
RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class); RootBeanDefinition csInterceptorDef = new RootBeanDefinition(ConversionServiceExposingInterceptor.class);
@ -128,8 +133,33 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef); mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedCsInterceptorDef); String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedCsInterceptorDef);
RootBeanDefinition annExceptionResolver = new RootBeanDefinition(AnnotationMethodHandlerExceptionResolver.class);
annExceptionResolver.setSource(source);
annExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
annExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
annExceptionResolver.getPropertyValues().add("order", 0);
String annExceptionResolverName =
parserContext.getReaderContext().registerWithGeneratedName(annExceptionResolver);
RootBeanDefinition responseStatusExceptionResolver = new RootBeanDefinition(ResponseStatusExceptionResolver.class);
responseStatusExceptionResolver.setSource(source);
responseStatusExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
responseStatusExceptionResolver.getPropertyValues().add("order", 1);
String responseStatusExceptionResolverName =
parserContext.getReaderContext().registerWithGeneratedName(responseStatusExceptionResolver);
RootBeanDefinition defaultExceptionResolver = new RootBeanDefinition(DefaultHandlerExceptionResolver.class);
defaultExceptionResolver.setSource(source);
defaultExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
defaultExceptionResolver.getPropertyValues().add("order", 2);
String defaultExceptionResolverName =
parserContext.getReaderContext().registerWithGeneratedName(defaultExceptionResolver);
parserContext.registerComponent(new BeanComponentDefinition(annMappingDef, annMappingName)); parserContext.registerComponent(new BeanComponentDefinition(annMappingDef, annMappingName));
parserContext.registerComponent(new BeanComponentDefinition(annAdapterDef, annAdapterName)); parserContext.registerComponent(new BeanComponentDefinition(annAdapterDef, annAdapterName));
parserContext.registerComponent(new BeanComponentDefinition(annExceptionResolver, annExceptionResolverName));
parserContext.registerComponent(new BeanComponentDefinition(responseStatusExceptionResolver, responseStatusExceptionResolverName));
parserContext.registerComponent(new BeanComponentDefinition(defaultExceptionResolver, defaultExceptionResolverName));
parserContext.registerComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName)); parserContext.registerComponent(new BeanComponentDefinition(mappedCsInterceptorDef, mappedInterceptorName));
parserContext.popAndRegisterContainingComponent(); parserContext.popAndRegisterContainingComponent();

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2010 the original author or authors. * Copyright 2002-2011 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -18,12 +18,10 @@ package org.springframework.web.servlet.config;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import javax.servlet.RequestDispatcher; import javax.servlet.RequestDispatcher;
import javax.validation.Valid; import javax.validation.Valid;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -64,6 +62,8 @@ import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.theme.ThemeChangeInterceptor; import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
import static org.junit.Assert.*;
/** /**
* @author Keith Donald * @author Keith Donald
* @author Arjen Poutsma * @author Arjen Poutsma
@ -84,7 +84,7 @@ public class MvcNamespaceTests {
public void testDefaultConfig() throws Exception { public void testDefaultConfig() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config.xml", getClass()));
assertEquals(5, appContext.getBeanDefinitionCount()); assertEquals(8, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class); DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class);
@ -124,7 +124,7 @@ public class MvcNamespaceTests {
public void testCustomConversionService() throws Exception { public void testCustomConversionService() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-custom-conversion-service.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-custom-conversion-service.xml", getClass()));
assertEquals(5, appContext.getBeanDefinitionCount()); assertEquals(8, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class); DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class);
@ -154,7 +154,7 @@ public class MvcNamespaceTests {
public void testCustomValidator() throws Exception { public void testCustomValidator() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-custom-validator.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-custom-validator.xml", getClass()));
assertEquals(5, appContext.getBeanDefinitionCount()); assertEquals(8, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
AnnotationMethodHandlerAdapter adapter = appContext.getBean(AnnotationMethodHandlerAdapter.class); AnnotationMethodHandlerAdapter adapter = appContext.getBean(AnnotationMethodHandlerAdapter.class);
@ -176,7 +176,7 @@ public class MvcNamespaceTests {
public void testInterceptors() throws Exception { public void testInterceptors() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-interceptors.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-interceptors.xml", getClass()));
assertEquals(8, appContext.getBeanDefinitionCount()); assertEquals(11, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class); DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class);
@ -279,7 +279,7 @@ public class MvcNamespaceTests {
} }
@Test @Test
public void testDefaultServletHandlerWithOptionalAtrributes() throws Exception { public void testDefaultServletHandlerWithOptionalAttributes() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-default-servlet-optional-attrs.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-default-servlet-optional-attrs.xml", getClass()));
assertEquals(3, appContext.getBeanDefinitionCount()); assertEquals(3, appContext.getBeanDefinitionCount());
@ -311,7 +311,7 @@ public class MvcNamespaceTests {
public void testBeanDecoration() throws Exception { public void testBeanDecoration() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-bean-decoration.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-bean-decoration.xml", getClass()));
assertEquals(7, appContext.getBeanDefinitionCount()); assertEquals(10, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class); DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class);
@ -335,7 +335,7 @@ public class MvcNamespaceTests {
public void testViewControllers() throws Exception { public void testViewControllers() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-view-controllers.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-view-controllers.xml", getClass()));
assertEquals(9, appContext.getBeanDefinitionCount()); assertEquals(12, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class); DefaultAnnotationHandlerMapping mapping = appContext.getBean(DefaultAnnotationHandlerMapping.class);
@ -394,7 +394,7 @@ public class MvcNamespaceTests {
public void testViewControllersOnWebSphere() throws Exception { public void testViewControllersOnWebSphere() throws Exception {
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
reader.loadBeanDefinitions(new ClassPathResource("mvc-config-view-controllers.xml", getClass())); reader.loadBeanDefinitions(new ClassPathResource("mvc-config-view-controllers.xml", getClass()));
assertEquals(9, appContext.getBeanDefinitionCount()); assertEquals(12, appContext.getBeanDefinitionCount());
appContext.refresh(); appContext.refresh();
SimpleUrlHandlerMapping mapping2 = appContext.getBean(SimpleUrlHandlerMapping.class); SimpleUrlHandlerMapping mapping2 = appContext.getBean(SimpleUrlHandlerMapping.class);