Browse Source

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

pull/1234/head
Juergen Hoeller 15 years ago
parent
commit
284f98f12a
  1. 45
      org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java
  2. 10
      org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java

45
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java

@ -1662,10 +1662,44 @@ public class ServletAnnotationControllerTests { @@ -1662,10 +1662,44 @@ public class ServletAnnotationControllerTests {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/handle");
MockHttpServletResponse response = new MockHttpServletResponse();
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
public void requestMappingBaseClass() throws Exception {
initServlet(MyAbstractControllerImpl.class);
@ -2940,17 +2974,18 @@ public class ServletAnnotationControllerTests { @@ -2940,17 +2974,18 @@ public class ServletAnnotationControllerTests {
}
@Controller
public interface IMyController {
@RequestMapping("/handle")
void handle(Writer writer) throws IOException;
void handle(Writer writer, @RequestParam(value="p", required=false) String param) throws IOException;
}
@Controller
public static class IMyControllerImpl implements IMyController {
public void handle(Writer writer) throws IOException {
writer.write("handle");
public void handle(Writer writer, @RequestParam(value="p", required=false) String param) throws IOException {
writer.write("handle " + param);
}
}

10
org.springframework.web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java

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

Loading…
Cancel
Save