Upgrade to Servlet API 4.0 for MVC and merge EhCache 3 tests into spring-context-support

Includes general streamlining of dependency declarations with reduced version variables, direct use of EclipseLink 2.7 and its implicit JPA 2.2 dependency in spring-orm, mixed use of Hibernate 5.2.10 and 5.1.10 for integration tests, as well as an upgrade to Jetty 9.4.7 RC0 and a downgrade to Groovy 2.4.12 (since Groovy 2.5 won't be final in time for Spring Framework 5.0).

Issue: SPR-15879
Issue: SPR-15880
This commit is contained in:
Juergen Hoeller
2017-08-21 01:34:11 +02:00
parent 3991ab4a23
commit fac1f236c3
9 changed files with 210 additions and 247 deletions

View File

@@ -19,7 +19,6 @@ package org.springframework.web.servlet.mvc.method.annotation;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Method;
import java.security.Principal;
import java.time.ZoneId;
import java.util.Locale;
@@ -27,12 +26,12 @@ import java.util.TimeZone;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.PushBuilder;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;
@@ -66,8 +65,18 @@ import org.springframework.web.servlet.support.RequestContextUtils;
public class ServletRequestMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Nullable
private static final Method newPushBuilderMethod =
ClassUtils.getMethodIfAvailable(HttpServletRequest.class, "newPushBuilder");
private static Class<?> pushBuilder;
static {
try {
pushBuilder = ClassUtils.forName("javax.servlet.http.PushBuilder",
ServletRequestMethodArgumentResolver.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
// Servlet 4.0 PushBuilder not found - not supported for injection
pushBuilder = null;
}
}
@Override
@@ -77,7 +86,7 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume
ServletRequest.class.isAssignableFrom(paramType) ||
MultipartRequest.class.isAssignableFrom(paramType) ||
HttpSession.class.isAssignableFrom(paramType) ||
(newPushBuilderMethod != null && newPushBuilderMethod.getReturnType().isAssignableFrom(paramType)) ||
(pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) ||
Principal.class.isAssignableFrom(paramType) ||
InputStream.class.isAssignableFrom(paramType) ||
Reader.class.isAssignableFrom(paramType) ||
@@ -130,13 +139,8 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume
}
return session;
}
else if (newPushBuilderMethod != null && newPushBuilderMethod.getReturnType().isAssignableFrom(paramType)) {
Object pushBuilder = ReflectionUtils.invokeMethod(newPushBuilderMethod, request);
if (pushBuilder != null && !paramType.isInstance(pushBuilder)) {
throw new IllegalStateException(
"Current push builder is not of type [" + paramType.getName() + "]: " + pushBuilder);
}
return pushBuilder;
else if (pushBuilder != null && pushBuilder.isAssignableFrom(paramType)) {
return PushBuilderDelegate.resolvePushBuilder(request, paramType);
}
else if (InputStream.class.isAssignableFrom(paramType)) {
InputStream inputStream = request.getInputStream();
@@ -181,4 +185,22 @@ public class ServletRequestMethodArgumentResolver implements HandlerMethodArgume
throw new UnsupportedOperationException("Unknown parameter type: " + paramType.getName());
}
/**
* Inner class to avoid a hard dependency on Servlet API 4.0 at runtime.
*/
private static class PushBuilderDelegate {
@Nullable
public static Object resolvePushBuilder(HttpServletRequest request, Class<?> paramType) {
PushBuilder pushBuilder = request.newPushBuilder();
if (pushBuilder != null && !paramType.isInstance(pushBuilder)) {
throw new IllegalStateException(
"Current push builder is not of type [" + paramType.getName() + "]: " + pushBuilder);
}
return pushBuilder;
}
}
}

View File

@@ -25,9 +25,11 @@ import java.util.Locale;
import java.util.TimeZone;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.PushBuilder;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpMethod;
@@ -46,6 +48,7 @@ import static org.junit.Assert.*;
/**
* @author Arjen Poutsma
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Nicholas Williams
*/
public class ServletRequestMethodArgumentResolverTests {
@@ -70,7 +73,7 @@ public class ServletRequestMethodArgumentResolverTests {
method = getClass().getMethod("supportedParams", ServletRequest.class, MultipartRequest.class,
HttpSession.class, Principal.class, Locale.class, InputStream.class, Reader.class,
WebRequest.class, TimeZone.class, ZoneId.class, HttpMethod.class);
WebRequest.class, TimeZone.class, ZoneId.class, HttpMethod.class, PushBuilder.class);
}
@@ -99,12 +102,7 @@ public class ServletRequestMethodArgumentResolverTests {
@Test
public void principal() throws Exception {
Principal principal = new Principal() {
@Override
public String getName() {
return "Foo";
}
};
Principal principal = () -> "Foo";
servletRequest.setUserPrincipal(principal);
MethodParameter principalParameter = new MethodParameter(method, 3);
@@ -228,6 +226,24 @@ public class ServletRequestMethodArgumentResolverTests {
assertSame("Invalid result", HttpMethod.valueOf(webRequest.getRequest().getMethod()), result);
}
@Test
public void pushBuilder() throws Exception {
final PushBuilder pushBuilder = Mockito.mock(PushBuilder.class);
servletRequest = new MockHttpServletRequest("GET", "") {
@Override
public PushBuilder newPushBuilder() {
return pushBuilder;
}
};
ServletWebRequest webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
MethodParameter pushBuilderParameter = new MethodParameter(method, 11);
assertTrue("PushBuilder not supported", resolver.supportsParameter(pushBuilderParameter));
Object result = resolver.resolveArgument(pushBuilderParameter, null, webRequest, null);
assertSame("Invalid result", pushBuilder, result);
}
@SuppressWarnings("unused")
public void supportedParams(ServletRequest p0,
@@ -240,7 +256,8 @@ public class ServletRequestMethodArgumentResolverTests {
WebRequest p7,
TimeZone p8,
ZoneId p9,
HttpMethod p10) {
HttpMethod p10,
PushBuilder p11) {
}
}