Proper exception for controller method return types that do not work with MvcUriComponentsBuilder (e.g. final classes)

Issue: SPR-16710
This commit is contained in:
Juergen Hoeller
2018-04-11 16:50:38 +02:00
parent ba13950d3a
commit 98536e1387
2 changed files with 97 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -252,10 +252,8 @@ public class MvcUriComponentsBuilder {
* controller.getAddressesForCountry("US")
* builder = MvcUriComponentsBuilder.fromMethodCall(controller);
* </pre>
*
* <p><strong>Note:</strong> This method extracts values from "Forwarded"
* and "X-Forwarded-*" headers if found. See class-level docs.
*
* @param info either the value returned from a "mock" controller
* invocation or the "mock" controller itself after an invocation
* @return a UriComponents instance
@@ -725,6 +723,16 @@ public class MvcUriComponentsBuilder {
}
public interface MethodInvocationInfo {
Class<?> getControllerType();
Method getControllerMethod();
Object[] getArgumentValues();
}
private static class ControllerMethodInvocationInterceptor
implements org.springframework.cglib.proxy.MethodInterceptor, MethodInterceptor {
@@ -737,27 +745,27 @@ public class MvcUriComponentsBuilder {
private static final Method getControllerType =
ReflectionUtils.findMethod(MethodInvocationInfo.class, "getControllerType");
private final Class<?> controllerType;
private Method controllerMethod;
private Object[] argumentValues;
private Class<?> controllerType;
ControllerMethodInvocationInterceptor(Class<?> controllerType) {
this.controllerType = controllerType;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
if (getControllerMethod.equals(method)) {
if (getControllerType.equals(method)) {
return this.controllerType;
}
else if (getControllerMethod.equals(method)) {
return this.controllerMethod;
}
else if (getArgumentValues.equals(method)) {
return this.argumentValues;
}
else if (getControllerType.equals(method)) {
return this.controllerType;
}
else if (ReflectionUtils.isObjectMethod(method)) {
return ReflectionUtils.invokeMethod(method, obj, args);
}
@@ -765,7 +773,13 @@ public class MvcUriComponentsBuilder {
this.controllerMethod = method;
this.argumentValues = args;
Class<?> returnType = method.getReturnType();
return (void.class == returnType ? null : returnType.cast(initProxy(returnType, this)));
try {
return (returnType == void.class ? null : returnType.cast(initProxy(returnType, this)));
}
catch (Throwable ex) {
throw new IllegalStateException(
"Failed to create proxy for controller method return type: " + method, ex);
}
}
}
@@ -776,16 +790,6 @@ public class MvcUriComponentsBuilder {
}
public interface MethodInvocationInfo {
Method getControllerMethod();
Object[] getArgumentValues();
Class<?> getControllerType();
}
public static class MethodArgumentBuilder {
private final Class<?> controllerType;