fixed @MVC processing of parameter-level annotations to work with interface-based proxies again (SPR-7483)

This commit is contained in:
Juergen Hoeller 2010-09-08 14:45:00 +00:00
parent 907febd86e
commit 284f98f12a
2 changed files with 48 additions and 7 deletions

View File

@ -1662,10 +1662,44 @@ public class ServletAnnotationControllerTests {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/handle"); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/handle");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response); servlet.service(request, response);
assertEquals("handle", response.getContentAsString()); assertEquals("handle null", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/handle");
request.addParameter("p", "value");
response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("handle value", response.getContentAsString());
} }
@Test
public void requestMappingInterfaceWithProxy() throws Exception {
DispatcherServlet servlet = new DispatcherServlet() {
@Override
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
GenericWebApplicationContext wac = new GenericWebApplicationContext();
wac.registerBeanDefinition("controller", new RootBeanDefinition(IMyControllerImpl.class));
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
autoProxyCreator.setBeanFactory(wac.getBeanFactory());
wac.getBeanFactory().addBeanPostProcessor(autoProxyCreator);
wac.getBeanFactory().registerSingleton("advisor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
wac.refresh();
return wac;
}
};
servlet.init(new MockServletConfig());
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/handle");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("handle null", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/handle");
request.addParameter("p", "value");
response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("handle value", response.getContentAsString());
}
@Test @Test
public void requestMappingBaseClass() throws Exception { public void requestMappingBaseClass() throws Exception {
initServlet(MyAbstractControllerImpl.class); initServlet(MyAbstractControllerImpl.class);
@ -2940,17 +2974,18 @@ public class ServletAnnotationControllerTests {
} }
@Controller
public interface IMyController { public interface IMyController {
@RequestMapping("/handle") @RequestMapping("/handle")
void handle(Writer writer) throws IOException; void handle(Writer writer, @RequestParam(value="p", required=false) String param) throws IOException;
} }
@Controller @Controller
public static class IMyControllerImpl implements IMyController { public static class IMyControllerImpl implements IMyController {
public void handle(Writer writer) throws IOException { public void handle(Writer writer, @RequestParam(value="p", required=false) String param) throws IOException {
writer.write("handle"); writer.write("handle " + param);
} }
} }

View File

@ -17,6 +17,7 @@
package org.springframework.web.bind.annotation.support; package org.springframework.web.bind.annotation.support;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
@ -72,12 +73,17 @@ public class HandlerMethodResolver {
*/ */
public void init(final Class<?> handlerType) { public void init(final Class<?> handlerType) {
Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>(); Set<Class<?>> handlerTypes = new LinkedHashSet<Class<?>>();
handlerTypes.add(handlerType); Class<?> specificHandlerType = null;
if (!Proxy.isProxyClass(handlerType)) {
handlerTypes.add(handlerType);
specificHandlerType = handlerType;
}
handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces())); handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces()));
for (Class<?> currentHandlerType : handlerTypes) { for (Class<?> currentHandlerType : handlerTypes) {
final Class<?> targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() { ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) { public void doWith(Method method) {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, handlerType); Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
if (isHandlerMethod(specificMethod) && if (isHandlerMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isHandlerMethod(bridgedMethod))) { (bridgedMethod == specificMethod || !isHandlerMethod(bridgedMethod))) {