Enable asyncSupported flag in Spring Test MVC
Also remove Servlet 3 bridge classes no longer needed since Spring Framework 4 compiles with the Servlet 3 API. That means applications may need to run tests with the Servlet 3 API jar although technically they don't have to run with that in production.
This commit is contained in:
@@ -1,145 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.test.web.servlet.request;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.AsyncEvent;
|
||||
import javax.servlet.AsyncListener;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.util.WebUtils;
|
||||
|
||||
/**
|
||||
* Mock implementation of the {@link AsyncContext} interface.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
class MockAsyncContext implements AsyncContext {
|
||||
|
||||
private final HttpServletRequest request;
|
||||
|
||||
private final HttpServletResponse response;
|
||||
|
||||
private final List<AsyncListener> listeners = new ArrayList<AsyncListener>();
|
||||
|
||||
private String dispatchedPath;
|
||||
|
||||
private long timeout = 10 * 1000L; // 10 seconds is Tomcat's default
|
||||
|
||||
|
||||
public MockAsyncContext(ServletRequest request, ServletResponse response) {
|
||||
this.request = (HttpServletRequest) request;
|
||||
this.response = (HttpServletResponse) response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletRequest getRequest() {
|
||||
return this.request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletResponse getResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasOriginalRequestAndResponse() {
|
||||
return (this.request instanceof MockHttpServletRequest) && (this.response instanceof MockHttpServletResponse);
|
||||
}
|
||||
|
||||
public String getDispatchedPath() {
|
||||
return this.dispatchedPath;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch() {
|
||||
dispatch(this.request.getRequestURI());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(String path) {
|
||||
dispatch(null, path);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatch(ServletContext context, String path) {
|
||||
this.dispatchedPath = path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void complete() {
|
||||
Servlet3MockHttpServletRequest mockRequest = WebUtils.getNativeRequest(request, Servlet3MockHttpServletRequest.class);
|
||||
if (mockRequest != null) {
|
||||
mockRequest.setAsyncStarted(false);
|
||||
}
|
||||
for (AsyncListener listener : this.listeners) {
|
||||
try {
|
||||
listener.onComplete(new AsyncEvent(this, this.request, this.response));
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException("AsyncListener failure", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Runnable runnable) {
|
||||
runnable.run();
|
||||
}
|
||||
|
||||
public List<AsyncListener> getListeners() {
|
||||
return this.listeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(AsyncListener listener) {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(AsyncListener listener, ServletRequest request, ServletResponse response) {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends AsyncListener> T createListener(Class<T> clazz) throws ServletException {
|
||||
return BeanUtils.instantiateClass(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeout() {
|
||||
return this.timeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimeout(long timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -653,6 +653,8 @@ public class MockHttpServletRequestBuilder implements RequestBuilder, Mergeable
|
||||
Assert.notNull(request, "Post-processor [" + postProcessor.getClass().getName() + "] returned null");
|
||||
}
|
||||
|
||||
request.setAsyncSupported(true);
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.test.web.servlet.request;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
|
||||
/**
|
||||
* A Servlet 3 sub-class of MockHttpServletRequest.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
class Servlet3MockHttpServletRequest extends MockHttpServletRequest {
|
||||
|
||||
private boolean asyncStarted;
|
||||
|
||||
private MockAsyncContext asyncContext;
|
||||
|
||||
private Map<String, Part> parts = new HashMap<String, Part>();
|
||||
|
||||
|
||||
public Servlet3MockHttpServletRequest(ServletContext servletContext) {
|
||||
super(servletContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync() {
|
||||
return startAsync(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
|
||||
this.asyncStarted = true;
|
||||
this.asyncContext = new MockAsyncContext(request, response);
|
||||
return this.asyncContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
return this.asyncContext;
|
||||
}
|
||||
|
||||
public void setAsyncContext(MockAsyncContext asyncContext) {
|
||||
this.asyncContext = asyncContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
return DispatcherType.REQUEST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
return this.asyncStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsyncStarted(boolean asyncStarted) {
|
||||
this.asyncStarted = asyncStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPart(Part part) {
|
||||
this.parts.put(part.getName(), part);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Part getPart(String key) throws IOException, IllegalStateException, ServletException {
|
||||
return this.parts.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
|
||||
return this.parts.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.test.web.servlet.request;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.AsyncContext;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Part;
|
||||
|
||||
import org.springframework.mock.web.MockMultipartHttpServletRequest;
|
||||
|
||||
/**
|
||||
* A Servlet 3 sub-class of MockMultipartHttpServletRequest.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
class Servlet3MockMultipartHttpServletRequest extends MockMultipartHttpServletRequest {
|
||||
|
||||
private boolean asyncStarted;
|
||||
|
||||
private MockAsyncContext asyncContext;
|
||||
|
||||
private Map<String, Part> parts = new HashMap<String, Part>();
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAsyncSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync() {
|
||||
return startAsync(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
|
||||
this.asyncStarted = true;
|
||||
this.asyncContext = new MockAsyncContext(request, response);
|
||||
return this.asyncContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AsyncContext getAsyncContext() {
|
||||
return this.asyncContext;
|
||||
}
|
||||
|
||||
public void setAsyncContext(MockAsyncContext asyncContext) {
|
||||
this.asyncContext = asyncContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DispatcherType getDispatcherType() {
|
||||
return DispatcherType.REQUEST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsyncStarted() {
|
||||
return this.asyncStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAsyncStarted(boolean asyncStarted) {
|
||||
this.asyncStarted = asyncStarted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPart(Part part) {
|
||||
this.parts.put(part.getName(), part);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Part getPart(String key) throws IOException, IllegalStateException, ServletException {
|
||||
return this.parts.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Part> getParts() throws IOException, IllegalStateException, ServletException {
|
||||
return this.parts.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -47,6 +47,7 @@ import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
@@ -107,6 +108,8 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
|
||||
|
||||
private boolean useTrailingSlashPatternMatch = true;
|
||||
|
||||
private Boolean removeSemicolonContent;
|
||||
|
||||
|
||||
/**
|
||||
* Protected constructor. Not intended for direct instantiation.
|
||||
@@ -274,6 +277,15 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set if ";" (semicolon) content should be stripped from the request URI. The value,
|
||||
* if provided, is in turn set on
|
||||
* {@link AbstractHandlerMapping#setRemoveSemicolonContent(boolean)}.
|
||||
*/
|
||||
public void setRemoveSemicolonContent(boolean removeSemicolonContent) {
|
||||
this.removeSemicolonContent = removeSemicolonContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initWebAppContext(WebApplicationContext cxt) {
|
||||
StubWebApplicationContext mockCxt = (StubWebApplicationContext) cxt;
|
||||
@@ -336,6 +348,10 @@ public class StandaloneMockMvcBuilder extends DefaultMockMvcBuilder<StandaloneMo
|
||||
handlerMapping.setOrder(0);
|
||||
handlerMapping.setInterceptors(getInterceptors());
|
||||
|
||||
if (removeSemicolonContent != null) {
|
||||
handlerMapping.setRemoveSemicolonContent(removeSemicolonContent);
|
||||
}
|
||||
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user