Skip to content

Commit 98536e1

Browse files
committed
Proper exception for controller method return types that do not work with MvcUriComponentsBuilder (e.g. final classes)
Issue: SPR-16710
1 parent ba13950 commit 98536e1

File tree

2 files changed

+97
-67
lines changed

2 files changed

+97
-67
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -252,10 +252,8 @@ public static UriComponentsBuilder fromMethodName(UriComponentsBuilder builder,
252252
* controller.getAddressesForCountry("US")
253253
* builder = MvcUriComponentsBuilder.fromMethodCall(controller);
254254
* </pre>
255-
*
256255
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
257256
* and "X-Forwarded-*" headers if found. See class-level docs.
258-
*
259257
* @param info either the value returned from a "mock" controller
260258
* invocation or the "mock" controller itself after an invocation
261259
* @return a UriComponents instance
@@ -725,6 +723,16 @@ public UriComponentsBuilder withMethod(Class<?> controllerType, Method method, O
725723
}
726724

727725

726+
public interface MethodInvocationInfo {
727+
728+
Class<?> getControllerType();
729+
730+
Method getControllerMethod();
731+
732+
Object[] getArgumentValues();
733+
}
734+
735+
728736
private static class ControllerMethodInvocationInterceptor
729737
implements org.springframework.cglib.proxy.MethodInterceptor, MethodInterceptor {
730738

@@ -737,35 +745,41 @@ private static class ControllerMethodInvocationInterceptor
737745
private static final Method getControllerType =
738746
ReflectionUtils.findMethod(MethodInvocationInfo.class, "getControllerType");
739747

748+
private final Class<?> controllerType;
749+
740750
private Method controllerMethod;
741751

742752
private Object[] argumentValues;
743753

744-
private Class<?> controllerType;
745-
746754
ControllerMethodInvocationInterceptor(Class<?> controllerType) {
747755
this.controllerType = controllerType;
748756
}
749757

750758
@Override
751759
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
752-
if (getControllerMethod.equals(method)) {
760+
if (getControllerType.equals(method)) {
761+
return this.controllerType;
762+
}
763+
else if (getControllerMethod.equals(method)) {
753764
return this.controllerMethod;
754765
}
755766
else if (getArgumentValues.equals(method)) {
756767
return this.argumentValues;
757768
}
758-
else if (getControllerType.equals(method)) {
759-
return this.controllerType;
760-
}
761769
else if (ReflectionUtils.isObjectMethod(method)) {
762770
return ReflectionUtils.invokeMethod(method, obj, args);
763771
}
764772
else {
765773
this.controllerMethod = method;
766774
this.argumentValues = args;
767775
Class<?> returnType = method.getReturnType();
768-
return (void.class == returnType ? null : returnType.cast(initProxy(returnType, this)));
776+
try {
777+
return (returnType == void.class ? null : returnType.cast(initProxy(returnType, this)));
778+
}
779+
catch (Throwable ex) {
780+
throw new IllegalStateException(
781+
"Failed to create proxy for controller method return type: " + method, ex);
782+
}
769783
}
770784
}
771785

@@ -776,16 +790,6 @@ public Object invoke(org.aopalliance.intercept.MethodInvocation inv) throws Thro
776790
}
777791

778792

779-
public interface MethodInvocationInfo {
780-
781-
Method getControllerMethod();
782-
783-
Object[] getArgumentValues();
784-
785-
Class<?> getControllerType();
786-
}
787-
788-
789793
public static class MethodArgumentBuilder {
790794

791795
private final Class<?> controllerType;

0 commit comments

Comments
 (0)