MockHttpServletRequest allows for removing registered header values

Includes full alignment of spring-test vs spring-web mock variants.

Issue: SPR-17295
This commit is contained in:
Juergen Hoeller
2018-09-23 14:44:15 +02:00
parent 9e2912e1dd
commit 51ba322947
17 changed files with 208 additions and 72 deletions

View File

@@ -23,6 +23,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@@ -38,7 +39,7 @@ class HeaderValueHolder {
private final List<Object> values = new LinkedList<>();
public void setValue(Object value) {
public void setValue(@Nullable Object value) {
this.values.clear();
if (value != null) {
this.values.add(value);
@@ -69,10 +70,12 @@ class HeaderValueHolder {
return Collections.unmodifiableList(stringList);
}
@Nullable
public Object getValue() {
return (!this.values.isEmpty() ? this.values.get(0) : null);
}
@Nullable
public String getStringValue() {
return (!this.values.isEmpty() ? String.valueOf(this.values.get(0)) : null);
}
@@ -90,6 +93,7 @@ class HeaderValueHolder {
* @return the corresponding HeaderValueHolder,
* or {@code null} if none found
*/
@Nullable
public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) {
Assert.notNull(name, "Header name must not be null");
for (String headerName : headers.keySet()) {

View File

@@ -116,7 +116,7 @@ public class MockAsyncContext implements AsyncContext {
@Override
public void complete() {
MockHttpServletRequest mockRequest = WebUtils.getNativeRequest(request, MockHttpServletRequest.class);
MockHttpServletRequest mockRequest = WebUtils.getNativeRequest(this.request, MockHttpServletRequest.class);
if (mockRequest != null) {
mockRequest.setAsyncStarted(false);
}
@@ -154,6 +154,17 @@ public class MockAsyncContext implements AsyncContext {
return BeanUtils.instantiateClass(clazz);
}
/**
* By default this is set to 10000 (10 seconds) even though the Servlet API
* specifies a default async request timeout of 30 seconds. Keep in mind the
* timeout could further be impacted by global configuration through the MVC
* Java config or the XML namespace, as well as be overridden per request on
* {@link org.springframework.web.context.request.async.DeferredResult DeferredResult}
* or on
* {@link org.springframework.web.servlet.mvc.method.annotation.SseEmitter SseEmitter}.
* @param timeout the timeout value to use.
* @see AsyncContext#setTimeout(long)
*/
@Override
public void setTimeout(long timeout) {
this.timeout = timeout;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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,6 +24,8 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import org.springframework.lang.Nullable;
/**
* Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class.
* Only necessary for testing applications when testing custom JSP tags.
@@ -60,12 +62,12 @@ public class MockBodyContent extends BodyContent {
* @param response the servlet response to wrap
* @param targetWriter the target Writer to wrap
*/
public MockBodyContent(String content, HttpServletResponse response, Writer targetWriter) {
public MockBodyContent(String content, @Nullable HttpServletResponse response, @Nullable Writer targetWriter) {
super(adaptJspWriter(targetWriter, response));
this.content = content;
}
private static JspWriter adaptJspWriter(Writer targetWriter, HttpServletResponse response) {
private static JspWriter adaptJspWriter(@Nullable Writer targetWriter, @Nullable HttpServletResponse response) {
if (targetWriter instanceof JspWriter) {
return (JspWriter) targetWriter;
}

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.
@@ -29,6 +29,7 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -49,12 +50,15 @@ import org.springframework.util.ObjectUtils;
*/
public class MockFilterChain implements FilterChain {
@Nullable
private ServletRequest request;
@Nullable
private ServletResponse response;
private final List<Filter> filters;
@Nullable
private Iterator<Filter> iterator;
@@ -97,6 +101,7 @@ public class MockFilterChain implements FilterChain {
/**
* Return the request that {@link #doFilter} has been called with.
*/
@Nullable
public ServletRequest getRequest() {
return this.request;
}
@@ -104,12 +109,13 @@ public class MockFilterChain implements FilterChain {
/**
* Return the response that {@link #doFilter} has been called with.
*/
@Nullable
public ServletResponse getResponse() {
return this.response;
}
/**
* Invoke registered {@link Filter}s and/or {@link Servlet} also saving the
* Invoke registered {@link Filter Filters} and/or {@link Servlet} also saving the
* request and response.
*/
@Override
@@ -144,7 +150,7 @@ public class MockFilterChain implements FilterChain {
/**
* A filter that simply delegates to a Servlet.
*/
private static class ServletFilterProxy implements Filter {
private static final class ServletFilterProxy implements Filter {
private final Servlet delegateServlet;

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.
@@ -23,6 +23,7 @@ import java.util.Map;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -64,7 +65,7 @@ public class MockFilterConfig implements FilterConfig {
* Create a new MockFilterConfig.
* @param servletContext the ServletContext that the servlet runs in
*/
public MockFilterConfig(ServletContext servletContext) {
public MockFilterConfig(@Nullable ServletContext servletContext) {
this(servletContext, "");
}
@@ -73,7 +74,7 @@ public class MockFilterConfig implements FilterConfig {
* @param servletContext the ServletContext that the servlet runs in
* @param filterName the name of the filter
*/
public MockFilterConfig(ServletContext servletContext, String filterName) {
public MockFilterConfig(@Nullable ServletContext servletContext, String filterName) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.filterName = filterName;
}
@@ -81,12 +82,12 @@ public class MockFilterConfig implements FilterConfig {
@Override
public String getFilterName() {
return filterName;
return this.filterName;
}
@Override
public ServletContext getServletContext() {
return servletContext;
return this.servletContext;
}
public void addInitParameter(String name, String value) {

View File

@@ -58,6 +58,7 @@ import javax.servlet.http.Part;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.util.LinkedMultiValueMap;
@@ -101,7 +102,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
new BufferedReader(new StringReader(""));
/**
* Date formats as specified in the HTTP RFC
* Date formats as specified in the HTTP RFC.
* @see <a href="https://tools.ietf.org/html/rfc7231#section-7.1.1.1">Section 7.1.1.1 of RFC 7231</a>
*/
private static final String[] DATE_FORMATS = new String[] {
@@ -168,14 +169,19 @@ public class MockHttpServletRequest implements HttpServletRequest {
private final Map<String, Object> attributes = new LinkedHashMap<>();
@Nullable
private String characterEncoding;
@Nullable
private byte[] content;
@Nullable
private String contentType;
@Nullable
private ServletInputStream inputStream;
@Nullable
private BufferedReader reader;
private final Map<String, String[]> parameters = new LinkedHashMap<>(16);
@@ -192,7 +198,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
private String remoteHost = DEFAULT_REMOTE_HOST;
/** List of locales in descending order */
/** List of locales in descending order. */
private final List<Locale> locales = new LinkedList<>();
private boolean secure = false;
@@ -209,6 +215,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
private boolean asyncSupported = false;
@Nullable
private MockAsyncContext asyncContext;
private DispatcherType dispatcherType = DispatcherType.REQUEST;
@@ -218,32 +225,42 @@ public class MockHttpServletRequest implements HttpServletRequest {
// HttpServletRequest properties
// ---------------------------------------------------------------------
@Nullable
private String authType;
@Nullable
private Cookie[] cookies;
private final Map<String, HeaderValueHolder> headers = new LinkedCaseInsensitiveMap<>();
@Nullable
private String method;
@Nullable
private String pathInfo;
private String contextPath = "";
@Nullable
private String queryString;
@Nullable
private String remoteUser;
private final Set<String> userRoles = new HashSet<>();
@Nullable
private Principal userPrincipal;
@Nullable
private String requestedSessionId;
@Nullable
private String requestURI;
private String servletPath = "";
@Nullable
private HttpSession session;
private boolean requestedSessionIdValid = true;
@@ -277,7 +294,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setRequestURI
* @see #MockHttpServletRequest(ServletContext, String, String)
*/
public MockHttpServletRequest(String method, String requestURI) {
public MockHttpServletRequest(@Nullable String method, @Nullable String requestURI) {
this(null, method, requestURI);
}
@@ -287,7 +304,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* (may be {@code null} to use a default {@link MockServletContext})
* @see #MockHttpServletRequest(ServletContext, String, String)
*/
public MockHttpServletRequest(ServletContext servletContext) {
public MockHttpServletRequest(@Nullable ServletContext servletContext) {
this(servletContext, "", "");
}
@@ -304,7 +321,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setPreferredLocales
* @see MockServletContext
*/
public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) {
public MockHttpServletRequest(@Nullable ServletContext servletContext, @Nullable String method, @Nullable String requestURI) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.method = method;
this.requestURI = requestURI;
@@ -373,12 +390,13 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public String getCharacterEncoding() {
return this.characterEncoding;
}
@Override
public void setCharacterEncoding(String characterEncoding) {
public void setCharacterEncoding(@Nullable String characterEncoding) {
this.characterEncoding = characterEncoding;
updateContentTypeHeader();
}
@@ -403,7 +421,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #getContentAsByteArray()
* @see #getContentAsString()
*/
public void setContent(byte[] content) {
public void setContent(@Nullable byte[] content) {
this.content = content;
}
@@ -414,6 +432,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setContent(byte[])
* @see #getContentAsString()
*/
@Nullable
public byte[] getContentAsByteArray() {
return this.content;
}
@@ -429,6 +448,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* @see #setCharacterEncoding(String)
* @see #getContentAsByteArray()
*/
@Nullable
public String getContentAsString() throws IllegalStateException, UnsupportedEncodingException {
Assert.state(this.characterEncoding != null,
"Cannot get content as a String for a null character encoding. " +
@@ -450,7 +470,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
return getContentLength();
}
public void setContentType(String contentType) {
public void setContentType(@Nullable String contentType) {
this.contentType = contentType;
if (contentType != null) {
try {
@@ -471,6 +491,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public String getContentType() {
return this.contentType;
}
@@ -536,7 +557,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
* <p>If there are already one or more values registered for the given
* parameter name, the given value will be added to the end of the list.
*/
public void addParameter(String name, String value) {
public void addParameter(String name, @Nullable String value) {
addParameter(name, new String[] {value});
}
@@ -596,6 +617,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public String getParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
String[] arr = this.parameters.get(name);
@@ -725,7 +747,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
public void setAttribute(String name, Object value) {
public void setAttribute(String name, @Nullable Object value) {
checkActive();
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
@@ -763,8 +785,8 @@ public class MockHttpServletRequest implements HttpServletRequest {
/**
* Set the list of preferred locales, in descending order, effectively replacing
* any existing locales.
* @see #addPreferredLocale
* @since 3.2
* @see #addPreferredLocale
*/
public void setPreferredLocales(List<Locale> locales) {
Assert.notEmpty(locales, "Locale list must not be empty");
@@ -889,7 +911,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
public AsyncContext startAsync(ServletRequest request, @Nullable ServletResponse response) {
Assert.state(this.asyncSupported, "Async not supported");
this.asyncStarted = true;
this.asyncContext = new MockAsyncContext(request, response);
@@ -914,11 +936,12 @@ public class MockHttpServletRequest implements HttpServletRequest {
return this.asyncSupported;
}
public void setAsyncContext(MockAsyncContext asyncContext) {
public void setAsyncContext(@Nullable MockAsyncContext asyncContext) {
this.asyncContext = asyncContext;
}
@Override
@Nullable
public AsyncContext getAsyncContext() {
return this.asyncContext;
}
@@ -937,16 +960,17 @@ public class MockHttpServletRequest implements HttpServletRequest {
// HttpServletRequest interface
// ---------------------------------------------------------------------
public void setAuthType(String authType) {
public void setAuthType(@Nullable String authType) {
this.authType = authType;
}
@Override
@Nullable
public String getAuthType() {
return this.authType;
}
public void setCookies(Cookie... cookies) {
public void setCookies(@Nullable Cookie... cookies) {
this.cookies = (ObjectUtils.isEmpty(cookies) ? null : cookies);
this.headers.remove(HttpHeaders.COOKIE);
if (this.cookies != null) {
@@ -957,14 +981,15 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public Cookie[] getCookies() {
return this.cookies;
}
/**
* Add a header entry for the given name.
* <p>While this method can take any {@code Object} as a parameter, it
* is recommended to use the following types:
* Add an HTTP header entry for the given name.
* <p>While this method can take any {@code Object} as a parameter,
* it is recommended to use the following types:
* <ul>
* <li>String or any Object to be converted using {@code toString()}; see {@link #getHeader}.</li>
* <li>String, Number, or Date for date headers; see {@link #getDateHeader}.</li>
@@ -998,7 +1023,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
}
private void doAddHeaderValue(String name, Object value, boolean replace) {
private void doAddHeaderValue(String name, @Nullable Object value, boolean replace) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
Assert.notNull(value, "Header value must not be null");
if (header == null || replace) {
@@ -1016,6 +1041,15 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
}
/**
* Remove already registered values for the specified HTTP header, if any.
* @since 5.1.1
*/
public void removeHeader(String name) {
Assert.notNull(name, "Header name must not be null");
this.headers.remove(name);
}
/**
* Return the long timestamp for the date header with the given {@code name}.
* <p>If the internal value representation is a String, this method will try
@@ -1065,6 +1099,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public String getHeader(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getStringValue() : null);
@@ -1099,25 +1134,28 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
}
public void setMethod(String method) {
public void setMethod(@Nullable String method) {
this.method = method;
}
@Override
@Nullable
public String getMethod() {
return this.method;
}
public void setPathInfo(String pathInfo) {
public void setPathInfo(@Nullable String pathInfo) {
this.pathInfo = pathInfo;
}
@Override
@Nullable
public String getPathInfo() {
return this.pathInfo;
}
@Override
@Nullable
public String getPathTranslated() {
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
}
@@ -1131,20 +1169,22 @@ public class MockHttpServletRequest implements HttpServletRequest {
return this.contextPath;
}
public void setQueryString(String queryString) {
public void setQueryString(@Nullable String queryString) {
this.queryString = queryString;
}
@Override
@Nullable
public String getQueryString() {
return this.queryString;
}
public void setRemoteUser(String remoteUser) {
public void setRemoteUser(@Nullable String remoteUser) {
this.remoteUser = remoteUser;
}
@Override
@Nullable
public String getRemoteUser() {
return this.remoteUser;
}
@@ -1159,29 +1199,32 @@ public class MockHttpServletRequest implements HttpServletRequest {
((MockServletContext) this.servletContext).getDeclaredRoles().contains(role)));
}
public void setUserPrincipal(Principal userPrincipal) {
public void setUserPrincipal(@Nullable Principal userPrincipal) {
this.userPrincipal = userPrincipal;
}
@Override
@Nullable
public Principal getUserPrincipal() {
return this.userPrincipal;
}
public void setRequestedSessionId(String requestedSessionId) {
public void setRequestedSessionId(@Nullable String requestedSessionId) {
this.requestedSessionId = requestedSessionId;
}
@Override
@Nullable
public String getRequestedSessionId() {
return this.requestedSessionId;
}
public void setRequestURI(String requestURI) {
public void setRequestURI(@Nullable String requestURI) {
this.requestURI = requestURI;
}
@Override
@Nullable
public String getRequestURI() {
return this.requestURI;
}
@@ -1222,6 +1265,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public HttpSession getSession(boolean create) {
checkActive();
// Reset session if invalidated.
@@ -1236,6 +1280,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public HttpSession getSession() {
return getSession(true);
}
@@ -1249,7 +1294,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
public String changeSessionId() {
Assert.isTrue(this.session != null, "The request does not have a session");
if (this.session instanceof MockHttpSession) {
return ((MockHttpSession) session).changeSessionId();
return ((MockHttpSession) this.session).changeSessionId();
}
return this.session.getId();
}
@@ -1309,6 +1354,7 @@ public class MockHttpServletRequest implements HttpServletRequest {
}
@Override
@Nullable
public Part getPart(String name) throws IOException, ServletException {
return this.parts.getFirst(name);
}

View File

@@ -29,6 +29,7 @@ import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -84,7 +85,7 @@ public class MockHttpSession implements HttpSession {
* Create a new MockHttpSession.
* @param servletContext the ServletContext that the session runs in
*/
public MockHttpSession(ServletContext servletContext) {
public MockHttpSession(@Nullable ServletContext servletContext) {
this(servletContext, null);
}
@@ -93,7 +94,7 @@ public class MockHttpSession implements HttpSession {
* @param servletContext the ServletContext that the session runs in
* @param id a unique identifier for this session
*/
public MockHttpSession(ServletContext servletContext, String id) {
public MockHttpSession(@Nullable ServletContext servletContext, @Nullable String id) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.id = (id != null ? id : Integer.toString(nextId++));
}
@@ -176,7 +177,7 @@ public class MockHttpSession implements HttpSession {
}
@Override
public void setAttribute(String name, Object value) {
public void setAttribute(String name, @Nullable Object value) {
assertIsValid();
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 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.
@@ -22,6 +22,8 @@ import java.io.Writer;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;
import org.springframework.lang.Nullable;
/**
* Mock implementation of the {@link javax.servlet.jsp.JspWriter} class.
* Only necessary for testing applications when testing custom JSP tags.
@@ -33,6 +35,7 @@ public class MockJspWriter extends JspWriter {
private final HttpServletResponse response;
@Nullable
private PrintWriter targetWriter;
@@ -58,7 +61,7 @@ public class MockJspWriter extends JspWriter {
* @param response the servlet response to wrap
* @param targetWriter the target Writer to wrap
*/
public MockJspWriter(HttpServletResponse response, Writer targetWriter) {
public MockJspWriter(@Nullable HttpServletResponse response, @Nullable Writer targetWriter) {
super(DEFAULT_BUFFER, true);
this.response = (response != null ? response : new MockHttpServletResponse());
if (targetWriter instanceof PrintWriter) {

View File

@@ -21,6 +21,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
@@ -43,6 +44,7 @@ public class MockMultipartFile implements MultipartFile {
private String originalFilename;
@Nullable
private String contentType;
private final byte[] content;
@@ -53,7 +55,7 @@ public class MockMultipartFile implements MultipartFile {
* @param name the name of the file
* @param content the content of the file
*/
public MockMultipartFile(String name, byte[] content) {
public MockMultipartFile(String name, @Nullable byte[] content) {
this(name, "", null, content);
}
@@ -74,7 +76,9 @@ public class MockMultipartFile implements MultipartFile {
* @param contentType the content type (if known)
* @param content the content of the file
*/
public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
public MockMultipartFile(
String name, @Nullable String originalFilename, @Nullable String contentType, @Nullable byte[] content) {
Assert.hasLength(name, "Name must not be null");
this.name = name;
this.originalFilename = (originalFilename != null ? originalFilename : "");
@@ -90,7 +94,8 @@ public class MockMultipartFile implements MultipartFile {
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream)
public MockMultipartFile(
String name, @Nullable String originalFilename, @Nullable String contentType, InputStream contentStream)
throws IOException {
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
@@ -108,6 +113,7 @@ public class MockMultipartFile implements MultipartFile {
}
@Override
@Nullable
public String getContentType() {
return this.contentType;
}

View File

@@ -25,6 +25,7 @@ import javax.servlet.ServletContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
@@ -65,7 +66,7 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl
* @param servletContext the ServletContext that the request runs in
* (may be {@code null} to use a default {@link MockServletContext})
*/
public MockMultipartHttpServletRequest(ServletContext servletContext) {
public MockMultipartHttpServletRequest(@Nullable ServletContext servletContext) {
super(servletContext);
setMethod("POST");
setContentType("multipart/form-data");

View File

@@ -36,6 +36,7 @@ import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -61,6 +62,7 @@ public class MockPageContext extends PageContext {
private final Map<String, Object> attributes = new LinkedHashMap<>();
@Nullable
private JspWriter out;
@@ -79,7 +81,7 @@ public class MockPageContext extends PageContext {
* @param servletContext the ServletContext that the JSP page runs in
* (only necessary when actually accessing the ServletContext)
*/
public MockPageContext(ServletContext servletContext) {
public MockPageContext(@Nullable ServletContext servletContext) {
this(servletContext, null, null, null);
}
@@ -90,7 +92,7 @@ public class MockPageContext extends PageContext {
* @param request the current HttpServletRequest
* (only necessary when actually accessing the request)
*/
public MockPageContext(ServletContext servletContext, HttpServletRequest request) {
public MockPageContext(@Nullable ServletContext servletContext, @Nullable HttpServletRequest request) {
this(servletContext, request, null, null);
}
@@ -101,7 +103,9 @@ public class MockPageContext extends PageContext {
* @param response the current HttpServletResponse
* (only necessary when actually writing to the response)
*/
public MockPageContext(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) {
public MockPageContext(@Nullable ServletContext servletContext, @Nullable HttpServletRequest request,
@Nullable HttpServletResponse response) {
this(servletContext, request, response, null);
}
@@ -112,8 +116,8 @@ public class MockPageContext extends PageContext {
* @param response the current HttpServletResponse
* @param servletConfig the ServletConfig (hardly ever accessed from within a tag)
*/
public MockPageContext(ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response, ServletConfig servletConfig) {
public MockPageContext(@Nullable ServletContext servletContext, @Nullable HttpServletRequest request,
@Nullable HttpServletResponse response, @Nullable ServletConfig servletConfig) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.request = (request != null ? request : new MockHttpServletRequest(servletContext));
@@ -135,7 +139,7 @@ public class MockPageContext extends PageContext {
}
@Override
public void setAttribute(String name, Object value) {
public void setAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
this.attributes.put(name, value);
@@ -146,7 +150,7 @@ public class MockPageContext extends PageContext {
}
@Override
public void setAttribute(String name, Object value, int scope) {
public void setAttribute(String name, @Nullable Object value, int scope) {
Assert.notNull(name, "Attribute name must not be null");
switch (scope) {
case PAGE_SCOPE:
@@ -167,12 +171,14 @@ public class MockPageContext extends PageContext {
}
@Override
@Nullable
public Object getAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
return this.attributes.get(name);
}
@Override
@Nullable
public Object getAttribute(String name, int scope) {
Assert.notNull(name, "Attribute name must not be null");
switch (scope) {
@@ -191,6 +197,7 @@ public class MockPageContext extends PageContext {
}
@Override
@Nullable
public Object findAttribute(String name) {
Object value = getAttribute(name);
if (value == null) {
@@ -290,12 +297,14 @@ public class MockPageContext extends PageContext {
}
@Override
@Nullable
public ELContext getELContext() {
return null;
}
@Override
@Deprecated
@Nullable
public javax.servlet.jsp.el.VariableResolver getVariableResolver() {
return null;
}
@@ -321,6 +330,7 @@ public class MockPageContext extends PageContext {
}
@Override
@Nullable
public Exception getException() {
return null;
}

View File

@@ -25,6 +25,7 @@ import javax.servlet.http.Part;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -40,6 +41,7 @@ public class MockPart implements Part {
private final String name;
@Nullable
private final String filename;
private final byte[] content;
@@ -51,7 +53,7 @@ public class MockPart implements Part {
* Constructor for a part with byte[] content only.
* @see #getHeaders()
*/
public MockPart(String name, byte[] content) {
public MockPart(String name, @Nullable byte[] content) {
this(name, null, content);
}
@@ -59,7 +61,7 @@ public class MockPart implements Part {
* Constructor for a part with a filename and byte[] content.
* @see #getHeaders()
*/
public MockPart(String name, String filename, byte[] content) {
public MockPart(String name, @Nullable String filename, @Nullable byte[] content) {
Assert.hasLength(name, "'name' must not be empty");
this.name = name;
this.filename = filename;
@@ -74,11 +76,13 @@ public class MockPart implements Part {
}
@Override
@Nullable
public String getSubmittedFileName() {
return this.filename;
}
@Override
@Nullable
public String getContentType() {
MediaType contentType = this.headers.getContentType();
return (contentType != null ? contentType.toString() : null);
@@ -105,6 +109,7 @@ public class MockPart implements Part {
}
@Override
@Nullable
public String getHeader(String name) {
return this.headers.getFirst(name);
}

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -60,7 +61,7 @@ public class MockServletConfig implements ServletConfig {
* Create a new MockServletConfig.
* @param servletContext the ServletContext that the servlet runs in
*/
public MockServletConfig(ServletContext servletContext) {
public MockServletConfig(@Nullable ServletContext servletContext) {
this(servletContext, "");
}
@@ -69,7 +70,7 @@ public class MockServletConfig implements ServletConfig {
* @param servletContext the ServletContext that the servlet runs in
* @param servletName the name of the servlet
*/
public MockServletConfig(ServletContext servletContext, String servletName) {
public MockServletConfig(@Nullable ServletContext servletContext, String servletName) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.servletName = servletName;
}

View File

@@ -48,6 +48,7 @@ import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.MimeType;
@@ -129,14 +130,17 @@ public class MockServletContext implements ServletContext {
private final Set<String> declaredRoles = new LinkedHashSet<>();
@Nullable
private Set<SessionTrackingMode> sessionTrackingModes;
private final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig();
private int sessionTimeout;
@Nullable
private String requestCharacterEncoding;
@Nullable
private String responseCharacterEncoding;
private final Map<String, MediaType> mimeTypes = new LinkedHashMap<>();
@@ -165,7 +169,7 @@ public class MockServletContext implements ServletContext {
* and no base path.
* @param resourceLoader the ResourceLoader to use (or null for the default)
*/
public MockServletContext(ResourceLoader resourceLoader) {
public MockServletContext(@Nullable ResourceLoader resourceLoader) {
this("", resourceLoader);
}
@@ -178,7 +182,7 @@ public class MockServletContext implements ServletContext {
* @param resourceLoader the ResourceLoader to use (or null for the default)
* @see #registerNamedDispatcher
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
public MockServletContext(String resourceBasePath, @Nullable ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
this.resourceBasePath = resourceBasePath;
@@ -262,6 +266,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public String getMimeType(String filePath) {
String extension = StringUtils.getFilenameExtension(filePath);
if (this.mimeTypes.containsKey(extension)) {
@@ -285,6 +290,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public Set<String> getResourcePaths(String path) {
String actualPath = (path.endsWith("/") ? path : path + "/");
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
@@ -313,6 +319,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public URL getResource(String path) throws MalformedURLException {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
if (!resource.exists()) {
@@ -333,6 +340,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public InputStream getResourceAsStream(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
if (!resource.exists()) {
@@ -414,6 +422,7 @@ public class MockServletContext implements ServletContext {
@Deprecated
@Override
@Nullable
public Servlet getServlet(String name) {
return null;
}
@@ -447,6 +456,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public String getRealPath(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
try {
@@ -492,6 +502,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public Object getAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
return this.attributes.get(name);
@@ -503,7 +514,7 @@ public class MockServletContext implements ServletContext {
}
@Override
public void setAttribute(String name, Object value) {
public void setAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
this.attributes.put(name, value);
@@ -529,6 +540,7 @@ public class MockServletContext implements ServletContext {
}
@Override
@Nullable
public ClassLoader getClassLoader() {
return ClassUtils.getDefaultClassLoader();
}
@@ -579,21 +591,23 @@ public class MockServletContext implements ServletContext {
}
@Override // on Servlet 4.0
public void setRequestCharacterEncoding(String requestCharacterEncoding) {
public void setRequestCharacterEncoding(@Nullable String requestCharacterEncoding) {
this.requestCharacterEncoding = requestCharacterEncoding;
}
@Override // on Servlet 4.0
@Nullable
public String getRequestCharacterEncoding() {
return this.requestCharacterEncoding;
}
@Override // on Servlet 4.0
public void setResponseCharacterEncoding(String responseCharacterEncoding) {
public void setResponseCharacterEncoding(@Nullable String responseCharacterEncoding) {
this.responseCharacterEncoding = responseCharacterEncoding;
}
@Override // on Servlet 4.0
@Nullable
public String getResponseCharacterEncoding() {
return this.responseCharacterEncoding;
}
@@ -638,6 +652,7 @@ public class MockServletContext implements ServletContext {
* @see javax.servlet.ServletContext#getServletRegistration(java.lang.String)
*/
@Override
@Nullable
public ServletRegistration getServletRegistration(String servletName) {
return null;
}
@@ -676,6 +691,7 @@ public class MockServletContext implements ServletContext {
* @see javax.servlet.ServletContext#getFilterRegistration(java.lang.String)
*/
@Override
@Nullable
public FilterRegistration getFilterRegistration(String filterName) {
return null;
}

View File

@@ -18,6 +18,8 @@ package org.springframework.mock.web.test;
import javax.servlet.SessionCookieConfig;
import org.springframework.lang.Nullable;
/**
* Mock implementation of the {@link javax.servlet.SessionCookieConfig} interface.
*
@@ -27,12 +29,16 @@ import javax.servlet.SessionCookieConfig;
*/
public class MockSessionCookieConfig implements SessionCookieConfig {
@Nullable
private String name;
@Nullable
private String domain;
@Nullable
private String path;
@Nullable
private String comment;
private boolean httpOnly;
@@ -43,41 +49,45 @@ public class MockSessionCookieConfig implements SessionCookieConfig {
@Override
public void setName(String name) {
public void setName(@Nullable String name) {
this.name = name;
}
@Override
@Nullable
public String getName() {
return this.name;
}
@Override
public void setDomain(String domain) {
public void setDomain(@Nullable String domain) {
this.domain = domain;
}
@Override
@Nullable
public String getDomain() {
return this.domain;
}
@Override
public void setPath(String path) {
public void setPath(@Nullable String path) {
this.path = path;
}
@Override
@Nullable
public String getPath() {
return this.path;
}
@Override
public void setComment(String comment) {
public void setComment(@Nullable String comment) {
this.comment = comment;
}
@Override
@Nullable
public String getComment() {
return this.comment;
}

View File

@@ -24,6 +24,7 @@ import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -40,10 +41,13 @@ import org.springframework.util.Assert;
*/
public class PassThroughFilterChain implements FilterChain {
@Nullable
private Filter filter;
@Nullable
private FilterChain nextFilterChain;
@Nullable
private Servlet servlet;