Support for Servlet 4.0 (PushBuilder argument, MockServletContext)

Issue: SPR-12674
This commit is contained in:
Juergen Hoeller
2017-02-13 15:06:59 +01:00
parent d44325ec91
commit 199aa776c9
32 changed files with 237 additions and 272 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -26,9 +26,7 @@ import javax.servlet.jsp.tagext.BodyContent;
/**
* Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
* Only necessary for testing applications when testing custom JSP tags.
*
* @author Juergen Hoeller
* @since 2.5

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2017 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.
@@ -21,12 +21,12 @@ import javax.servlet.jsp.PageContext;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
import org.springframework.util.Assert;
/**
* Mock implementation of the JSP 2.0 {@link javax.servlet.jsp.el.ExpressionEvaluator}
* interface, delegating to the Apache JSTL ExpressionEvaluatorManager.
*
* <p>Used for testing the web framework; only necessary for testing applications
* when testing custom JSP tags.
* Only necessary for testing applications when testing custom JSP tags.
*
* <p>Note that the Apache JSTL implementation (jstl.jar, standard.jar) has to be
* available on the class path to use this expression evaluator.
@@ -68,9 +68,7 @@ public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEval
public Object evaluate(String expression, Class expectedType, javax.servlet.jsp.el.VariableResolver variableResolver,
javax.servlet.jsp.el.FunctionMapper functionMapper) throws javax.servlet.jsp.el.ELException {
if (variableResolver != null) {
throw new IllegalArgumentException("Custom VariableResolver not supported");
}
Assert.isNull(variableResolver, "Custom VariableResolver not supported");
return doEvaluate(expression, expectedType, functionMapper);
}
@@ -78,9 +76,7 @@ public class MockExpressionEvaluator extends javax.servlet.jsp.el.ExpressionEval
protected Object doEvaluate(String expression, Class expectedType, javax.servlet.jsp.el.FunctionMapper functionMapper)
throws javax.servlet.jsp.el.ELException {
if (functionMapper != null) {
throw new IllegalArgumentException("Custom FunctionMapper not supported");
}
Assert.isNull(functionMapper, "Custom FunctionMapper not supported");
try {
return ExpressionEvaluatorManager.evaluate("JSP EL expression", expression, expectedType, this.pageContext);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -33,9 +33,7 @@ import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
/**
* <p>Mock implementation of the {@link javax.servlet.FilterChain} interface. Used
* for testing the web framework; also useful for testing custom
* {@link javax.servlet.Filter} implementations.
* Mock implementation of the {@link javax.servlet.FilterChain} interface.
*
* <p>A {@link MockFilterChain} can be configured with one or more filters and a
* Servlet to invoke. The first time the chain is called, it invokes all filters
@@ -120,10 +118,7 @@ public class MockFilterChain implements FilterChain {
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
if (this.request != null) {
throw new IllegalStateException("This FilterChain has already been called!");
}
Assert.state(this.request == null, "This FilterChain has already been called!");
if (this.iterator == null) {
this.iterator = this.filters.iterator();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.

View File

@@ -70,7 +70,7 @@ import org.springframework.util.StringUtils;
* is {@link Locale#ENGLISH}. This value can be changed via {@link #addPreferredLocale}
* or {@link #setPreferredLocales}.
*
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 3.1 baseline.
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
*
* @author Juergen Hoeller
* @author Rod Johnson

View File

@@ -45,7 +45,7 @@ import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface.
*
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 3.1 baseline.
* <p>As of Spring Framework 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
*
* @author Juergen Hoeller
* @author Rod Johnson

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -34,10 +34,7 @@ import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.http.HttpSession} interface.
*
* <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
*
* <p>Used for testing the web framework; also useful for testing application
* controllers.
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
*
* @author Juergen Hoeller
* @author Rod Johnson
@@ -72,7 +69,6 @@ public class MockHttpSession implements HttpSession {
/**
* Create a new MockHttpSession with a default {@link MockServletContext}.
*
* @see MockServletContext
*/
public MockHttpSession() {
@@ -81,7 +77,6 @@ public class MockHttpSession implements HttpSession {
/**
* Create a new MockHttpSession.
*
* @param servletContext the ServletContext that the session runs in
*/
public MockHttpSession(ServletContext servletContext) {
@@ -90,7 +85,6 @@ public class MockHttpSession implements HttpSession {
/**
* Create a new MockHttpSession.
*
* @param servletContext the ServletContext that the session runs in
* @param id a unique identifier for this session
*/
@@ -99,6 +93,7 @@ public class MockHttpSession implements HttpSession {
this.id = (id != null ? id : Integer.toString(nextId++));
}
@Override
public long getCreationTime() {
assertIsValid();
@@ -111,8 +106,8 @@ public class MockHttpSession implements HttpSession {
}
/**
* As of Servlet 3.1 the id of a session can be changed.
* @return the new session id.
* As of Servlet 3.1, the id of a session can be changed.
* @return the new session id
* @since 4.0.3
*/
public String changeSessionId() {
@@ -227,7 +222,6 @@ public class MockHttpSession implements HttpSession {
/**
* Invalidates this session then unbinds any objects bound to it.
*
* @throws IllegalStateException if this method is called on an already invalidated session
*/
@Override
@@ -244,13 +238,10 @@ public class MockHttpSession implements HttpSession {
/**
* Convenience method for asserting that this session has not been
* {@linkplain #invalidate() invalidated}.
*
* @throws IllegalStateException if this session has been invalidated
*/
private void assertIsValid() {
if (isInvalid()) {
throw new IllegalStateException("The session has already been invalidated");
}
Assert.state(!isInvalid(), "The session has already been invalidated");
}
public void setNew(boolean value) {
@@ -266,7 +257,6 @@ public class MockHttpSession implements HttpSession {
/**
* Serialize the attributes of this session into an object that can be
* turned into a byte array with standard Java serialization.
*
* @return a representation of this session's serialized state
*/
public Serializable serializeState() {
@@ -293,7 +283,6 @@ public class MockHttpSession implements HttpSession {
/**
* Deserialize the attributes of this session from a state object created by
* {@link #serializeState()}.
*
* @param state a representation of this session's serialized state
*/
@SuppressWarnings("unchecked")

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -24,9 +24,7 @@ import javax.servlet.jsp.JspWriter;
/**
* Mock implementation of the {@link javax.servlet.jsp.JspWriter} class.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
* Only necessary for testing applications when testing custom JSP tags.
*
* @author Juergen Hoeller
* @since 2.5

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -35,11 +35,10 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
* Mock implementation of the
* {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface.
*
* <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
*
* <p>Useful for testing application controllers that access multipart uploads.
* The {@link MockMultipartFile} can be used to populate these mock requests
* with files.
* {@link MockMultipartFile} can be used to populate these mock requests with files.
*
* @author Juergen Hoeller
* @author Eric Crampton
@@ -49,8 +48,7 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
*/
public class MockMultipartHttpServletRequest extends MockHttpServletRequest implements MultipartHttpServletRequest {
private final MultiValueMap<String, MultipartFile> multipartFiles =
new LinkedMultiValueMap<>();
private final MultiValueMap<String, MultipartFile> multipartFiles = new LinkedMultiValueMap<>();
/**

View File

@@ -40,9 +40,7 @@ import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.jsp.PageContext} interface.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
* Only necessary for testing applications when testing custom JSP tags.
*
* <p>Note: Expects initialization via the constructor rather than via the
* {@code PageContext.initialize} method. Does not support writing to a

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2017 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.
@@ -29,9 +29,6 @@ import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.RequestDispatcher} interface.
*
* <p>Used for testing the web framework; typically not necessary for
* testing application controllers.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
@@ -50,7 +47,7 @@ public class MockRequestDispatcher implements RequestDispatcher {
* particular path or given by a particular name
*/
public MockRequestDispatcher(String resource) {
Assert.notNull(resource, "resource must not be null");
Assert.notNull(resource, "Resource must not be null");
this.resource = resource;
}
@@ -59,9 +56,7 @@ public class MockRequestDispatcher implements RequestDispatcher {
public void forward(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
if (response.isCommitted()) {
throw new IllegalStateException("Cannot perform forward - response is already committed");
}
Assert.state(!response.isCommitted(), "Cannot perform forward - response is already committed");
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -28,9 +28,6 @@ import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.ServletConfig} interface.
*
* <p>Used for testing the web framework; typically not necessary for
* testing application controllers.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 1.0.2

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 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.
@@ -55,37 +55,21 @@ import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
*
* <p>As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline.
* <p>As of Spring 5.0, this set of mocks is designed on a Servlet 4.0 baseline.
*
* <p>Compatible with Servlet 3.0 but can be configured to expose a specific version
* through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.0.
* Note that Servlet 3.0 support is limited: servlet, filter and listener
* <p>Compatible with Servlet 3.1 but can be configured to expose a specific version
* through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.1.
* Note that Servlet 3.1 support is limited: servlet, filter and listener
* registration methods are not supported; neither is JSP configuration.
* We generally do not recommend to unit test your ServletContainerInitializers and
* WebApplicationInitializers which is where those registration methods would be used.
*
* <p>Used for testing the Spring web framework; only rarely necessary for testing
* application controllers. As long as application components don't explicitly
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
* {@code FileSystemXmlApplicationContext} can be used to load the context files
* for testing, even for {@code DispatcherServlet} context definitions.
*
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
* you can use {@code AnnotationConfigWebApplicationContext},
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
* passing in an appropriate {@code MockServletContext} instance. You might want
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
* in that case to ensure that resource paths are interpreted as relative filesystem
* locations.
*
* <p>A common setup is to point your JVM working directory to the root of your
* web application directory, in combination with filesystem-based resource loading.
* This allows to load the context files as used in the web application, with
* relative paths getting interpreted correctly. Such a setup will work with both
* {@code FileSystemXmlApplicationContext} (which will load straight from the
* filesystem) and {@code XmlWebApplicationContext} with an underlying
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
* configured with a {@code FileSystemResourceLoader}).
* <p>For setting up a full {@code WebApplicationContext} in a test environment, you can
* use {@code AnnotationConfigWebApplicationContext}, {@code XmlWebApplicationContext},
* or {@code GenericWebApplicationContext}, passing in a corresponding
* {@code MockServletContext} instance. Consider configuring your
* {@code MockServletContext} with a {@code FileSystemResourceLoader} in order to
* interpret resource paths as relative filesystem locations.
*
* @author Rod Johnson
* @author Juergen Hoeller
@@ -95,18 +79,15 @@ import org.springframework.web.util.WebUtils;
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
* @see org.springframework.context.support.FileSystemXmlApplicationContext
*/
public class MockServletContext implements ServletContext {
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value} */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private static final Set<SessionTrackingMode> DEFAULT_SESSION_TRACKING_MODES =
new LinkedHashSet<>(3);
private static final Set<SessionTrackingMode> DEFAULT_SESSION_TRACKING_MODES = new LinkedHashSet<>(4);
static {
DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.COOKIE);
@@ -127,11 +108,11 @@ public class MockServletContext implements ServletContext {
private int majorVersion = 3;
private int minorVersion = 0;
private int minorVersion = 1;
private int effectiveMajorVersion = 3;
private int effectiveMinorVersion = 0;
private int effectiveMinorVersion = 1;
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<>();
@@ -149,6 +130,8 @@ public class MockServletContext implements ServletContext {
private final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig();
private int sessionTimeout;
/**
* Create a new {@code MockServletContext}, using no base path and a
@@ -425,13 +408,13 @@ public class MockServletContext implements ServletContext {
@Override
@Deprecated
public Enumeration<Servlet> getServlets() {
return Collections.enumeration(Collections.<Servlet>emptySet());
return Collections.enumeration(Collections.emptySet());
}
@Override
@Deprecated
public Enumeration<String> getServletNames() {
return Collections.enumeration(Collections.<String>emptySet());
return Collections.enumeration(Collections.emptySet());
}
@Override
@@ -570,6 +553,16 @@ public class MockServletContext implements ServletContext {
return this.sessionCookieConfig;
}
// @Override - but only against Servlet 4.0
public void setSessionTimeout(int sessionTimeout) {
this.sessionTimeout = sessionTimeout;
}
// @Override - but only against Servlet 4.0
public int getSessionTimeout() {
return this.sessionTimeout;
}
//---------------------------------------------------------------------
// Unsupported Servlet 3.0 registration methods
@@ -580,6 +573,11 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
// @Override - but only against Servlet 4.0
public ServletRegistration.Dynamic addJspFile(String servletName, String jspFile) {
throw new UnsupportedOperationException();
}
@Override
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
throw new UnsupportedOperationException();