Moved tests from testsuite to web.servlet
This commit is contained in:
parent
327c54839b
commit
85d82f2244
|
|
@ -1,39 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
|
||||||
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
|
|
||||||
|
|
||||||
<bean id="requestScopedObject" class="org.springframework.beans.TestBean" scope="request"/>
|
|
||||||
|
|
||||||
<bean id="requestScopedDisposableObject" class="org.springframework.beans.DerivedTestBean" scope="request"/>
|
|
||||||
|
|
||||||
<bean id="requestScopedFactoryBean" class="org.springframework.beans.factory.DummyFactory" scope="request"/>
|
|
||||||
|
|
||||||
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<property name="spouse" ref="requestScopedObjectCircle2"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedObjectCircle2" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<property name="spouse" ref="requestScopedObjectCircle1"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedOuterBean" class="org.springframework.beans.DerivedTestBean" scope="request">
|
|
||||||
<property name="name" value="outer"/>
|
|
||||||
<property name="spouse">
|
|
||||||
<bean class="org.springframework.beans.DerivedTestBean">
|
|
||||||
<property name="name" value="inner"/>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="singletonOuterBean" class="org.springframework.beans.DerivedTestBean" lazy-init="true">
|
|
||||||
<property name="name" value="outer"/>
|
|
||||||
<property name="spouse">
|
|
||||||
<bean class="org.springframework.beans.DerivedTestBean" scope="request">
|
|
||||||
<property name="name" value="inner"/>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
|
||||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
|
||||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
|
|
||||||
|
|
||||||
<bean id="requestScopedObject" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
<property name="name" value="scoped"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedProxy" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<aop:scoped-proxy proxy-target-class="false"/>
|
|
||||||
<property name="name" value="scoped"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedDisposableObject" class="org.springframework.beans.DerivedTestBean" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
<property name="name" value="scoped"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedFactoryBean" class="org.springframework.beans.factory.DummyFactory" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedObjectCircle1" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
<property name="spouse" ref="requestScopedObjectCircle2"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="requestScopedObjectCircle2" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
<property name="spouse" ref="requestScopedObjectCircle1"/>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="outerBean" class="org.springframework.beans.TestBean">
|
|
||||||
<property name="spouse">
|
|
||||||
<bean id="scopedInnerBean" class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
<property name="name" value="scoped"/>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="outerBeanWithAnonymousInner" class="org.springframework.beans.TestBean">
|
|
||||||
<constructor-arg>
|
|
||||||
<bean class="org.springframework.beans.TestBean" scope="request">
|
|
||||||
<aop:scoped-proxy/>
|
|
||||||
<property name="name" value="scoped"/>
|
|
||||||
</bean>
|
|
||||||
</constructor-arg>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
|
||||||
|
|
||||||
<beans>
|
|
||||||
|
|
||||||
<bean id="sessionScopedObject" class="org.springframework.beans.TestBean" scope="session"/>
|
|
||||||
|
|
||||||
<bean id="sessionScopedDisposableObject" class="org.springframework.beans.DerivedTestBean" scope="session"/>
|
|
||||||
|
|
||||||
</beans>
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2008 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.web.servlet.mvc.annotation;
|
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
|
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
|
||||||
import org.springframework.mock.web.MockServletContext;
|
|
||||||
import org.springframework.web.context.support.XmlWebApplicationContext;
|
|
||||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Juergen Hoeller
|
|
||||||
*/
|
|
||||||
public class ControllerClassNameHandlerMappingTests extends TestCase {
|
|
||||||
|
|
||||||
public static final String LOCATION = "/org/springframework/web/servlet/mvc/annotation/class-mapping.xml";
|
|
||||||
|
|
||||||
private XmlWebApplicationContext wac;
|
|
||||||
|
|
||||||
private HandlerMapping hm;
|
|
||||||
|
|
||||||
private HandlerMapping hm2;
|
|
||||||
|
|
||||||
private HandlerMapping hm3;
|
|
||||||
|
|
||||||
private HandlerMapping hm4;
|
|
||||||
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
MockServletContext sc = new MockServletContext("");
|
|
||||||
this.wac = new XmlWebApplicationContext();
|
|
||||||
this.wac.setServletContext(sc);
|
|
||||||
this.wac.setConfigLocations(new String[] {LOCATION});
|
|
||||||
this.wac.refresh();
|
|
||||||
this.hm = (HandlerMapping) this.wac.getBean("mapping");
|
|
||||||
this.hm2 = (HandlerMapping) this.wac.getBean("mapping2");
|
|
||||||
this.hm3 = (HandlerMapping) this.wac.getBean("mapping3");
|
|
||||||
this.hm4 = (HandlerMapping) this.wac.getBean("mapping4");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testIndexUri() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index");
|
|
||||||
HandlerExecutionChain chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("index"), chain.getHandler());
|
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/index/product");
|
|
||||||
chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("index"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testMapSimpleUri() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/welcome");
|
|
||||||
HandlerExecutionChain chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("welcome"), chain.getHandler());
|
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/welcome/product");
|
|
||||||
chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("welcome"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testWithContextPath() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/welcome");
|
|
||||||
request.setContextPath("/myapp");
|
|
||||||
HandlerExecutionChain chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("welcome"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testWithoutControllerSuffix() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/buyform");
|
|
||||||
HandlerExecutionChain chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("buy"), chain.getHandler());
|
|
||||||
|
|
||||||
request = new MockHttpServletRequest("GET", "/buyform/product");
|
|
||||||
chain = this.hm.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("buy"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testWithBasePackage() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/mvc/annotation/welcome");
|
|
||||||
HandlerExecutionChain chain = this.hm2.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("welcome"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testWithBasePackageAndCaseSensitive() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/mvc/annotation/buyForm");
|
|
||||||
HandlerExecutionChain chain = this.hm2.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("buy"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testWithFullBasePackage() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/welcome");
|
|
||||||
HandlerExecutionChain chain = this.hm3.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("welcome"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testWithRootAsBasePackage() throws Exception {
|
|
||||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/org/springframework/web/servlet/mvc/annotation/welcome");
|
|
||||||
HandlerExecutionChain chain = this.hm4.getHandler(request);
|
|
||||||
assertEquals(this.wac.getBean("welcome"), chain.getHandler());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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.mock.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegating implementation of {@link javax.servlet.ServletInputStream}.
|
||||||
|
*
|
||||||
|
* <p>Used by {@link org.springframework.mock.web.MockHttpServletRequest}; typically not directly
|
||||||
|
* used for testing application controllers.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 1.0.2
|
||||||
|
* @see org.springframework.mock.web.MockHttpServletRequest
|
||||||
|
*/
|
||||||
|
public class DelegatingServletInputStream extends ServletInputStream {
|
||||||
|
|
||||||
|
private final InputStream sourceStream;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a DelegatingServletInputStream for the given source stream.
|
||||||
|
* @param sourceStream the source stream (never <code>null</code>)
|
||||||
|
*/
|
||||||
|
public DelegatingServletInputStream(InputStream sourceStream) {
|
||||||
|
Assert.notNull(sourceStream, "Source InputStream must not be null");
|
||||||
|
this.sourceStream = sourceStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the underlying source stream (never <code>null</code>).
|
||||||
|
*/
|
||||||
|
public final InputStream getSourceStream() {
|
||||||
|
return this.sourceStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
return this.sourceStream.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
super.close();
|
||||||
|
this.sourceStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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.mock.web;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegating implementation of {@link javax.servlet.ServletOutputStream}.
|
||||||
|
*
|
||||||
|
* <p>Used by {@link org.springframework.mock.web.MockHttpServletResponse}; typically not directly
|
||||||
|
* used for testing application controllers.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 1.0.2
|
||||||
|
* @see org.springframework.mock.web.MockHttpServletResponse
|
||||||
|
*/
|
||||||
|
public class DelegatingServletOutputStream extends ServletOutputStream {
|
||||||
|
|
||||||
|
private final OutputStream targetStream;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a DelegatingServletOutputStream for the given target stream.
|
||||||
|
* @param targetStream the target stream (never <code>null</code>)
|
||||||
|
*/
|
||||||
|
public DelegatingServletOutputStream(OutputStream targetStream) {
|
||||||
|
Assert.notNull(targetStream, "Target OutputStream must not be null");
|
||||||
|
this.targetStream = targetStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the underlying target stream (never <code>null</code>).
|
||||||
|
*/
|
||||||
|
public final OutputStream getTargetStream() {
|
||||||
|
return this.targetStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
this.targetStream.write(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException {
|
||||||
|
super.flush();
|
||||||
|
this.targetStream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() throws IOException {
|
||||||
|
super.close();
|
||||||
|
this.targetStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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.mock.web;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal helper class that serves as value holder for request headers.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @author Rick Evans
|
||||||
|
* @since 2.0.1
|
||||||
|
*/
|
||||||
|
class HeaderValueHolder {
|
||||||
|
|
||||||
|
private final List values = new LinkedList();
|
||||||
|
|
||||||
|
|
||||||
|
public void setValue(Object value) {
|
||||||
|
this.values.clear();
|
||||||
|
this.values.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addValue(Object value) {
|
||||||
|
this.values.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addValues(Collection values) {
|
||||||
|
this.values.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addValueArray(Object values) {
|
||||||
|
CollectionUtils.mergeArrayIntoCollection(values, this.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getValues() {
|
||||||
|
return Collections.unmodifiableList(this.values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue() {
|
||||||
|
return (!this.values.isEmpty() ? this.values.get(0) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a HeaderValueHolder by name, ignoring casing.
|
||||||
|
* @param headers the Map of header names to HeaderValueHolders
|
||||||
|
* @param name the name of the desired header
|
||||||
|
* @return the corresponding HeaderValueHolder,
|
||||||
|
* or <code>null</code> if none found
|
||||||
|
*/
|
||||||
|
public static HeaderValueHolder getByName(Map headers, String name) {
|
||||||
|
Assert.notNull(name, "Header name must not be null");
|
||||||
|
for (Iterator it = headers.keySet().iterator(); it.hasNext();) {
|
||||||
|
String headerName = (String) it.next();
|
||||||
|
if (headerName.equalsIgnoreCase(name)) {
|
||||||
|
return (HeaderValueHolder) headers.get(headerName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,858 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2008 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.mock.web;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.security.Principal;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock implementation of the {@link javax.servlet.http.HttpServletRequest}
|
||||||
|
* interface. Supports the Servlet 2.4 API level.
|
||||||
|
*
|
||||||
|
* <p>Used for testing the web framework; also useful for testing
|
||||||
|
* application controllers.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @author Rod Johnson
|
||||||
|
* @author Rick Evans
|
||||||
|
* @author Mark Fisher
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
public class MockHttpServletRequest implements HttpServletRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default protocol: 'http'.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_PROTOCOL = "http";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default server address: '127.0.0.1'.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_SERVER_ADDR = "127.0.0.1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default server name: 'localhost'.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_SERVER_NAME = "localhost";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default server port: '80'.
|
||||||
|
*/
|
||||||
|
public static final int DEFAULT_SERVER_PORT = 80;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default remote address: '127.0.0.1'.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default remote host: 'localhost'.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_REMOTE_HOST = "localhost";
|
||||||
|
|
||||||
|
|
||||||
|
private boolean active = true;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// ServletRequest properties
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
private final Hashtable attributes = new Hashtable();
|
||||||
|
|
||||||
|
private String characterEncoding;
|
||||||
|
|
||||||
|
private byte[] content;
|
||||||
|
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
private final Map parameters = new LinkedHashMap(16);
|
||||||
|
|
||||||
|
private String protocol = DEFAULT_PROTOCOL;
|
||||||
|
|
||||||
|
private String scheme = DEFAULT_PROTOCOL;
|
||||||
|
|
||||||
|
private String serverName = DEFAULT_SERVER_NAME;
|
||||||
|
|
||||||
|
private int serverPort = DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
|
private String remoteAddr = DEFAULT_REMOTE_ADDR;
|
||||||
|
|
||||||
|
private String remoteHost = DEFAULT_REMOTE_HOST;
|
||||||
|
|
||||||
|
/** List of locales in descending order */
|
||||||
|
private final Vector locales = new Vector();
|
||||||
|
|
||||||
|
private boolean secure = false;
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
private int remotePort = DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
|
private String localName = DEFAULT_SERVER_NAME;
|
||||||
|
|
||||||
|
private String localAddr = DEFAULT_SERVER_ADDR;
|
||||||
|
|
||||||
|
private int localPort = DEFAULT_SERVER_PORT;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HttpServletRequest properties
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
private String authType;
|
||||||
|
|
||||||
|
private Cookie[] cookies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key is the lowercase header name; the value is a {@link org.springframework.mock.web.HeaderValueHolder} object.
|
||||||
|
*/
|
||||||
|
private final Hashtable headers = new Hashtable();
|
||||||
|
|
||||||
|
private String method;
|
||||||
|
|
||||||
|
private String pathInfo;
|
||||||
|
|
||||||
|
private String contextPath = "";
|
||||||
|
|
||||||
|
private String queryString;
|
||||||
|
|
||||||
|
private String remoteUser;
|
||||||
|
|
||||||
|
private final Set userRoles = new HashSet();
|
||||||
|
|
||||||
|
private Principal userPrincipal;
|
||||||
|
|
||||||
|
private String requestURI;
|
||||||
|
|
||||||
|
private String servletPath = "";
|
||||||
|
|
||||||
|
private HttpSession session;
|
||||||
|
|
||||||
|
private boolean requestedSessionIdValid = true;
|
||||||
|
|
||||||
|
private boolean requestedSessionIdFromCookie = true;
|
||||||
|
|
||||||
|
private boolean requestedSessionIdFromURL = false;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Constructors
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpServletRequest with a default
|
||||||
|
* {@link org.springframework.mock.web.MockServletContext}.
|
||||||
|
* @see org.springframework.mock.web.MockServletContext
|
||||||
|
*/
|
||||||
|
public MockHttpServletRequest() {
|
||||||
|
this(null, "", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpServletRequest with a default
|
||||||
|
* {@link org.springframework.mock.web.MockServletContext}.
|
||||||
|
* @param method the request method (may be <code>null</code>)
|
||||||
|
* @param requestURI the request URI (may be <code>null</code>)
|
||||||
|
* @see #setMethod
|
||||||
|
* @see #setRequestURI
|
||||||
|
* @see org.springframework.mock.web.MockServletContext
|
||||||
|
*/
|
||||||
|
public MockHttpServletRequest(String method, String requestURI) {
|
||||||
|
this(null, method, requestURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpServletRequest.
|
||||||
|
* @param servletContext the ServletContext that the request runs in
|
||||||
|
* (may be <code>null</code> to use a default MockServletContext)
|
||||||
|
* @see org.springframework.mock.web.MockServletContext
|
||||||
|
*/
|
||||||
|
public MockHttpServletRequest(ServletContext servletContext) {
|
||||||
|
this(servletContext, "", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpServletRequest.
|
||||||
|
* @param servletContext the ServletContext that the request runs in
|
||||||
|
* (may be <code>null</code> to use a default MockServletContext)
|
||||||
|
* @param method the request method (may be <code>null</code>)
|
||||||
|
* @param requestURI the request URI (may be <code>null</code>)
|
||||||
|
* @see #setMethod
|
||||||
|
* @see #setRequestURI
|
||||||
|
* @see org.springframework.mock.web.MockServletContext
|
||||||
|
*/
|
||||||
|
public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) {
|
||||||
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
|
this.method = method;
|
||||||
|
this.requestURI = requestURI;
|
||||||
|
this.locales.add(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Lifecycle methods
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the ServletContext that this request is associated with.
|
||||||
|
* (Not available in the standard HttpServletRequest interface for some reason.)
|
||||||
|
*/
|
||||||
|
public ServletContext getServletContext() {
|
||||||
|
return this.servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether this request is still active (that is, not completed yet).
|
||||||
|
*/
|
||||||
|
public boolean isActive() {
|
||||||
|
return this.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark this request as completed, keeping its state.
|
||||||
|
*/
|
||||||
|
public void close() {
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidate this request, clearing its state.
|
||||||
|
*/
|
||||||
|
public void invalidate() {
|
||||||
|
close();
|
||||||
|
clearAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether this request is still active (that is, not completed yet),
|
||||||
|
* throwing an IllegalStateException if not active anymore.
|
||||||
|
*/
|
||||||
|
protected void checkActive() throws IllegalStateException {
|
||||||
|
if (!this.active) {
|
||||||
|
throw new IllegalStateException("Request is not active anymore");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// ServletRequest interface
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
public Object getAttribute(String name) {
|
||||||
|
checkActive();
|
||||||
|
return this.attributes.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getAttributeNames() {
|
||||||
|
checkActive();
|
||||||
|
return this.attributes.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCharacterEncoding() {
|
||||||
|
return this.characterEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharacterEncoding(String characterEncoding) {
|
||||||
|
this.characterEncoding = characterEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(byte[] content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getContentLength() {
|
||||||
|
return (this.content != null ? this.content.length : -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentType(String contentType) {
|
||||||
|
this.contentType = contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return this.contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServletInputStream getInputStream() {
|
||||||
|
if (this.content != null) {
|
||||||
|
return new DelegatingServletInputStream(new ByteArrayInputStream(this.content));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a single value for the specified HTTP parameter.
|
||||||
|
* <p>If there are already one or more values registered for the given
|
||||||
|
* parameter name, they will be replaced.
|
||||||
|
*/
|
||||||
|
public void setParameter(String name, String value) {
|
||||||
|
setParameter(name, new String[] {value});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set an array of values for the specified HTTP parameter.
|
||||||
|
* <p>If there are already one or more values registered for the given
|
||||||
|
* parameter name, they will be replaced.
|
||||||
|
*/
|
||||||
|
public void setParameter(String name, String[] values) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
this.parameters.put(name, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets all provided parameters <emphasis>replacing</emphasis> any
|
||||||
|
* existing values for the provided parameter names. To add without
|
||||||
|
* replacing existing values, use {@link #addParameters(java.util.Map)}.
|
||||||
|
*/
|
||||||
|
public void setParameters(Map params) {
|
||||||
|
Assert.notNull(params, "Parameter map must not be null");
|
||||||
|
for (Iterator it = params.keySet().iterator(); it.hasNext();) {
|
||||||
|
Object key = it.next();
|
||||||
|
Assert.isInstanceOf(String.class, key,
|
||||||
|
"Parameter map key must be of type [" + String.class.getName() + "]");
|
||||||
|
Object value = params.get(key);
|
||||||
|
if (value instanceof String) {
|
||||||
|
this.setParameter((String) key, (String) value);
|
||||||
|
}
|
||||||
|
else if (value instanceof String[]) {
|
||||||
|
this.setParameter((String) key, (String[]) value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException("Parameter map value must be single value " +
|
||||||
|
" or array of type [" + String.class.getName() + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a single value for the specified HTTP parameter.
|
||||||
|
* <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) {
|
||||||
|
addParameter(name, new String[] {value});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an array of values for the specified HTTP parameter.
|
||||||
|
* <p>If there are already one or more values registered for the given
|
||||||
|
* parameter name, the given values will be added to the end of the list.
|
||||||
|
*/
|
||||||
|
public void addParameter(String name, String[] values) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
String[] oldArr = (String[]) this.parameters.get(name);
|
||||||
|
if (oldArr != null) {
|
||||||
|
String[] newArr = new String[oldArr.length + values.length];
|
||||||
|
System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
|
||||||
|
System.arraycopy(values, 0, newArr, oldArr.length, values.length);
|
||||||
|
this.parameters.put(name, newArr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.parameters.put(name, values);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds all provided parameters <emphasis>without</emphasis> replacing
|
||||||
|
* any existing values. To replace existing values, use
|
||||||
|
* {@link #setParameters(java.util.Map)}.
|
||||||
|
*/
|
||||||
|
public void addParameters(Map params) {
|
||||||
|
Assert.notNull(params, "Parameter map must not be null");
|
||||||
|
for (Iterator it = params.keySet().iterator(); it.hasNext();) {
|
||||||
|
Object key = it.next();
|
||||||
|
Assert.isInstanceOf(String.class, key,
|
||||||
|
"Parameter map key must be of type [" + String.class.getName() + "]");
|
||||||
|
Object value = params.get(key);
|
||||||
|
if (value instanceof String) {
|
||||||
|
this.addParameter((String) key, (String) value);
|
||||||
|
}
|
||||||
|
else if (value instanceof String[]) {
|
||||||
|
this.addParameter((String) key, (String[]) value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException("Parameter map value must be single value " +
|
||||||
|
" or array of type [" + String.class.getName() + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove already registered values for the specified HTTP parameter, if any.
|
||||||
|
*/
|
||||||
|
public void removeParameter(String name) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
this.parameters.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all existing parameters.
|
||||||
|
*/
|
||||||
|
public void removeAllParameters() {
|
||||||
|
this.parameters.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getParameter(String name) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
String[] arr = (String[]) this.parameters.get(name);
|
||||||
|
return (arr != null && arr.length > 0 ? arr[0] : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getParameterNames() {
|
||||||
|
return Collections.enumeration(this.parameters.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getParameterValues(String name) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
return (String[]) this.parameters.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map getParameterMap() {
|
||||||
|
return Collections.unmodifiableMap(this.parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProtocol(String protocol) {
|
||||||
|
this.protocol = protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getProtocol() {
|
||||||
|
return this.protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScheme(String scheme) {
|
||||||
|
this.scheme = scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getScheme() {
|
||||||
|
return this.scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerName(String serverName) {
|
||||||
|
this.serverName = serverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerName() {
|
||||||
|
return this.serverName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServerPort(int serverPort) {
|
||||||
|
this.serverPort = serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getServerPort() {
|
||||||
|
return this.serverPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedReader getReader() throws UnsupportedEncodingException {
|
||||||
|
if (this.content != null) {
|
||||||
|
InputStream sourceStream = new ByteArrayInputStream(this.content);
|
||||||
|
Reader sourceReader = (this.characterEncoding != null) ?
|
||||||
|
new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream);
|
||||||
|
return new BufferedReader(sourceReader);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteAddr(String remoteAddr) {
|
||||||
|
this.remoteAddr = remoteAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemoteAddr() {
|
||||||
|
return this.remoteAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteHost(String remoteHost) {
|
||||||
|
this.remoteHost = remoteHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemoteHost() {
|
||||||
|
return this.remoteHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttribute(String name, Object value) {
|
||||||
|
checkActive();
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
if (value != null) {
|
||||||
|
this.attributes.put(name, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.attributes.remove(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAttribute(String name) {
|
||||||
|
checkActive();
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
this.attributes.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all of this request's attributes.
|
||||||
|
*/
|
||||||
|
public void clearAttributes() {
|
||||||
|
this.attributes.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new preferred locale, before any existing locales.
|
||||||
|
*/
|
||||||
|
public void addPreferredLocale(Locale locale) {
|
||||||
|
Assert.notNull(locale, "Locale must not be null");
|
||||||
|
this.locales.add(0, locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locale getLocale() {
|
||||||
|
return (Locale) this.locales.get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getLocales() {
|
||||||
|
return this.locales.elements();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSecure(boolean secure) {
|
||||||
|
this.secure = secure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSecure() {
|
||||||
|
return this.secure;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDispatcher getRequestDispatcher(String path) {
|
||||||
|
return new MockRequestDispatcher(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealPath(String path) {
|
||||||
|
return this.servletContext.getRealPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemotePort(int remotePort) {
|
||||||
|
this.remotePort = remotePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRemotePort() {
|
||||||
|
return this.remotePort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalName(String localName) {
|
||||||
|
this.localName = localName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalName() {
|
||||||
|
return this.localName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalAddr(String localAddr) {
|
||||||
|
this.localAddr = localAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocalAddr() {
|
||||||
|
return this.localAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocalPort(int localPort) {
|
||||||
|
this.localPort = localPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLocalPort() {
|
||||||
|
return this.localPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HttpServletRequest interface
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void setAuthType(String authType) {
|
||||||
|
this.authType = authType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAuthType() {
|
||||||
|
return this.authType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCookies(Cookie[] cookies) {
|
||||||
|
this.cookies = cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cookie[] getCookies() {
|
||||||
|
return this.cookies;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a header entry for the given name.
|
||||||
|
* <p>If there was no entry for that header name before,
|
||||||
|
* the value will be used as-is. In case of an existing entry,
|
||||||
|
* a String array will be created, adding the given value (more
|
||||||
|
* specifically, its toString representation) as further element.
|
||||||
|
* <p>Multiple values can only be stored as list of Strings,
|
||||||
|
* following the Servlet spec (see <code>getHeaders</code> accessor).
|
||||||
|
* As alternative to repeated <code>addHeader</code> calls for
|
||||||
|
* individual elements, you can use a single call with an entire
|
||||||
|
* array or Collection of values as parameter.
|
||||||
|
* @see #getHeaderNames
|
||||||
|
* @see #getHeader
|
||||||
|
* @see #getHeaders
|
||||||
|
* @see #getDateHeader
|
||||||
|
* @see #getIntHeader
|
||||||
|
*/
|
||||||
|
public void addHeader(String name, Object value) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
Assert.notNull(value, "Header value must not be null");
|
||||||
|
if (header == null) {
|
||||||
|
header = new HeaderValueHolder();
|
||||||
|
this.headers.put(name, header);
|
||||||
|
}
|
||||||
|
if (value instanceof Collection) {
|
||||||
|
header.addValues((Collection) value);
|
||||||
|
}
|
||||||
|
else if (value.getClass().isArray()) {
|
||||||
|
header.addValueArray(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header.addValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDateHeader(String name) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
Object value = (header != null ? header.getValue() : null);
|
||||||
|
if (value instanceof Date) {
|
||||||
|
return ((Date) value).getTime();
|
||||||
|
}
|
||||||
|
else if (value instanceof Number) {
|
||||||
|
return ((Number) value).longValue();
|
||||||
|
}
|
||||||
|
else if (value != null) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Value for header '" + name + "' is neither a Date nor a Number: " + value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHeader(String name) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
return (header != null ? header.getValue().toString() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getHeaders(String name) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
return Collections.enumeration(header != null ? header.getValues() : Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getHeaderNames() {
|
||||||
|
return this.headers.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIntHeader(String name) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
Object value = (header != null ? header.getValue() : null);
|
||||||
|
if (value instanceof Number) {
|
||||||
|
return ((Number) value).intValue();
|
||||||
|
}
|
||||||
|
else if (value instanceof String) {
|
||||||
|
return Integer.parseInt((String) value);
|
||||||
|
}
|
||||||
|
else if (value != null) {
|
||||||
|
throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMethod(String method) {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMethod() {
|
||||||
|
return this.method;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPathInfo(String pathInfo) {
|
||||||
|
this.pathInfo = pathInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPathInfo() {
|
||||||
|
return this.pathInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPathTranslated() {
|
||||||
|
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContextPath(String contextPath) {
|
||||||
|
this.contextPath = contextPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContextPath() {
|
||||||
|
return this.contextPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setQueryString(String queryString) {
|
||||||
|
this.queryString = queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getQueryString() {
|
||||||
|
return this.queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRemoteUser(String remoteUser) {
|
||||||
|
this.remoteUser = remoteUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRemoteUser() {
|
||||||
|
return this.remoteUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated in favor of addUserRole
|
||||||
|
* @see #addUserRole
|
||||||
|
*/
|
||||||
|
public void addRole(String role) {
|
||||||
|
addUserRole(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUserRole(String role) {
|
||||||
|
this.userRoles.add(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUserInRole(String role) {
|
||||||
|
return this.userRoles.contains(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserPrincipal(Principal userPrincipal) {
|
||||||
|
this.userPrincipal = userPrincipal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Principal getUserPrincipal() {
|
||||||
|
return this.userPrincipal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestedSessionId() {
|
||||||
|
HttpSession session = getSession();
|
||||||
|
return (session != null ? session.getId() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestURI(String requestURI) {
|
||||||
|
this.requestURI = requestURI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRequestURI() {
|
||||||
|
return this.requestURI;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StringBuffer getRequestURL() {
|
||||||
|
StringBuffer url = new StringBuffer(this.scheme);
|
||||||
|
url.append("://").append(this.serverName).append(':').append(this.serverPort);
|
||||||
|
url.append(getRequestURI());
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServletPath(String servletPath) {
|
||||||
|
this.servletPath = servletPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServletPath() {
|
||||||
|
return this.servletPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSession(HttpSession session) {
|
||||||
|
this.session = session;
|
||||||
|
if (session instanceof MockHttpSession) {
|
||||||
|
MockHttpSession mockSession = ((MockHttpSession) session);
|
||||||
|
mockSession.access();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpSession getSession(boolean create) {
|
||||||
|
checkActive();
|
||||||
|
// Reset session if invalidated.
|
||||||
|
if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) {
|
||||||
|
this.session = null;
|
||||||
|
}
|
||||||
|
// Create new session if necessary.
|
||||||
|
if (this.session == null && create) {
|
||||||
|
this.session = new MockHttpSession(this.servletContext);
|
||||||
|
}
|
||||||
|
return this.session;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpSession getSession() {
|
||||||
|
return getSession(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
|
||||||
|
this.requestedSessionIdValid = requestedSessionIdValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequestedSessionIdValid() {
|
||||||
|
return this.requestedSessionIdValid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) {
|
||||||
|
this.requestedSessionIdFromCookie = requestedSessionIdFromCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequestedSessionIdFromCookie() {
|
||||||
|
return this.requestedSessionIdFromCookie;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) {
|
||||||
|
this.requestedSessionIdFromURL = requestedSessionIdFromURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequestedSessionIdFromURL() {
|
||||||
|
return this.requestedSessionIdFromURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isRequestedSessionIdFromUrl() {
|
||||||
|
return isRequestedSessionIdFromURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,517 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2008 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.mock.web;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.Cookie;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.util.WebUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock implementation of the {@link javax.servlet.http.HttpServletResponse}
|
||||||
|
* interface. Supports the Servlet 2.4 API level.
|
||||||
|
*
|
||||||
|
* <p>Used for testing the web framework; also useful for testing
|
||||||
|
* application controllers.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @author Rod Johnson
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
public class MockHttpServletResponse implements HttpServletResponse {
|
||||||
|
|
||||||
|
public static final int DEFAULT_SERVER_PORT = 80;
|
||||||
|
|
||||||
|
private static final String CHARSET_PREFIX = "charset=";
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// ServletResponse properties
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
private boolean outputStreamAccessAllowed = true;
|
||||||
|
|
||||||
|
private boolean writerAccessAllowed = true;
|
||||||
|
|
||||||
|
private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
|
||||||
|
|
||||||
|
private final ByteArrayOutputStream content = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
private final ServletOutputStream outputStream = new ResponseServletOutputStream(this.content);
|
||||||
|
|
||||||
|
private PrintWriter writer;
|
||||||
|
|
||||||
|
private int contentLength = 0;
|
||||||
|
|
||||||
|
private String contentType;
|
||||||
|
|
||||||
|
private int bufferSize = 4096;
|
||||||
|
|
||||||
|
private boolean committed;
|
||||||
|
|
||||||
|
private Locale locale = Locale.getDefault();
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HttpServletResponse properties
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
private final List cookies = new ArrayList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The key is the lowercase header name; the value is a {@link org.springframework.mock.web.HeaderValueHolder} object.
|
||||||
|
*/
|
||||||
|
private final Map headers = new HashMap();
|
||||||
|
|
||||||
|
private int status = HttpServletResponse.SC_OK;
|
||||||
|
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
private String redirectedUrl;
|
||||||
|
|
||||||
|
private String forwardedUrl;
|
||||||
|
|
||||||
|
private String includedUrl;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// ServletResponse interface
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether {@link #getOutputStream()} access is allowed.
|
||||||
|
* <p>Default is <code>true</code>.
|
||||||
|
*/
|
||||||
|
public void setOutputStreamAccessAllowed(boolean outputStreamAccessAllowed) {
|
||||||
|
this.outputStreamAccessAllowed = outputStreamAccessAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether {@link #getOutputStream()} access is allowed.
|
||||||
|
*/
|
||||||
|
public boolean isOutputStreamAccessAllowed() {
|
||||||
|
return this.outputStreamAccessAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether {@link #getWriter()} access is allowed.
|
||||||
|
* <p>Default is <code>true</code>.
|
||||||
|
*/
|
||||||
|
public void setWriterAccessAllowed(boolean writerAccessAllowed) {
|
||||||
|
this.writerAccessAllowed = writerAccessAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether {@link #getOutputStream()} access is allowed.
|
||||||
|
*/
|
||||||
|
public boolean isWriterAccessAllowed() {
|
||||||
|
return this.writerAccessAllowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCharacterEncoding(String characterEncoding) {
|
||||||
|
this.characterEncoding = characterEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCharacterEncoding() {
|
||||||
|
return this.characterEncoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServletOutputStream getOutputStream() {
|
||||||
|
if (!this.outputStreamAccessAllowed) {
|
||||||
|
throw new IllegalStateException("OutputStream access not allowed");
|
||||||
|
}
|
||||||
|
return this.outputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrintWriter getWriter() throws UnsupportedEncodingException {
|
||||||
|
if (!this.writerAccessAllowed) {
|
||||||
|
throw new IllegalStateException("Writer access not allowed");
|
||||||
|
}
|
||||||
|
if (this.writer == null) {
|
||||||
|
Writer targetWriter = (this.characterEncoding != null ?
|
||||||
|
new OutputStreamWriter(this.content, this.characterEncoding) : new OutputStreamWriter(this.content));
|
||||||
|
this.writer = new ResponsePrintWriter(targetWriter);
|
||||||
|
}
|
||||||
|
return this.writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] getContentAsByteArray() {
|
||||||
|
flushBuffer();
|
||||||
|
return this.content.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentAsString() throws UnsupportedEncodingException {
|
||||||
|
flushBuffer();
|
||||||
|
return (this.characterEncoding != null) ?
|
||||||
|
this.content.toString(this.characterEncoding) : this.content.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentLength(int contentLength) {
|
||||||
|
this.contentLength = contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getContentLength() {
|
||||||
|
return this.contentLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContentType(String contentType) {
|
||||||
|
this.contentType = contentType;
|
||||||
|
if (contentType != null) {
|
||||||
|
int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
|
||||||
|
if (charsetIndex != -1) {
|
||||||
|
String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
|
||||||
|
setCharacterEncoding(encoding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContentType() {
|
||||||
|
return this.contentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBufferSize(int bufferSize) {
|
||||||
|
this.bufferSize = bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBufferSize() {
|
||||||
|
return this.bufferSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flushBuffer() {
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetBuffer() {
|
||||||
|
if (isCommitted()) {
|
||||||
|
throw new IllegalStateException("Cannot reset buffer - response is already committed");
|
||||||
|
}
|
||||||
|
this.content.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCommittedIfBufferSizeExceeded() {
|
||||||
|
int bufSize = getBufferSize();
|
||||||
|
if (bufSize > 0 && this.content.size() > bufSize) {
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCommitted(boolean committed) {
|
||||||
|
this.committed = committed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCommitted() {
|
||||||
|
return this.committed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reset() {
|
||||||
|
resetBuffer();
|
||||||
|
this.characterEncoding = null;
|
||||||
|
this.contentLength = 0;
|
||||||
|
this.contentType = null;
|
||||||
|
this.locale = null;
|
||||||
|
this.cookies.clear();
|
||||||
|
this.headers.clear();
|
||||||
|
this.status = HttpServletResponse.SC_OK;
|
||||||
|
this.errorMessage = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLocale(Locale locale) {
|
||||||
|
this.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Locale getLocale() {
|
||||||
|
return this.locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// HttpServletResponse interface
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void addCookie(Cookie cookie) {
|
||||||
|
Assert.notNull(cookie, "Cookie must not be null");
|
||||||
|
this.cookies.add(cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cookie[] getCookies() {
|
||||||
|
return (Cookie[]) this.cookies.toArray(new Cookie[this.cookies.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Cookie getCookie(String name) {
|
||||||
|
Assert.notNull(name, "Cookie name must not be null");
|
||||||
|
for (Iterator it = this.cookies.iterator(); it.hasNext();) {
|
||||||
|
Cookie cookie = (Cookie) it.next();
|
||||||
|
if (name.equals(cookie.getName())) {
|
||||||
|
return cookie;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsHeader(String name) {
|
||||||
|
return (HeaderValueHolder.getByName(this.headers, name) != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the names of all specified headers as a Set of Strings.
|
||||||
|
* @return the <code>Set</code> of header name <code>Strings</code>, or an empty <code>Set</code> if none
|
||||||
|
*/
|
||||||
|
public Set getHeaderNames() {
|
||||||
|
return this.headers.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the primary value for the given header, if any.
|
||||||
|
* <p>Will return the first value in case of multiple values.
|
||||||
|
* @param name the name of the header
|
||||||
|
* @return the associated header value, or <code>null<code> if none
|
||||||
|
*/
|
||||||
|
public Object getHeader(String name) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
return (header != null ? header.getValue() : null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all values for the given header as a List of value objects.
|
||||||
|
* @param name the name of the header
|
||||||
|
* @return the associated header values, or an empty List if none
|
||||||
|
*/
|
||||||
|
public List getHeaders(String name) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
return (header != null ? header.getValues() : Collections.EMPTY_LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation returns the given URL String as-is.
|
||||||
|
* <p>Can be overridden in subclasses, appending a session id or the like.
|
||||||
|
*/
|
||||||
|
public String encodeURL(String url) {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation delegates to {@link #encodeURL},
|
||||||
|
* returning the given URL String as-is.
|
||||||
|
* <p>Can be overridden in subclasses, appending a session id or the like
|
||||||
|
* in a redirect-specific fashion. For general URL encoding rules,
|
||||||
|
* override the common {@link #encodeURL} method instead, appyling
|
||||||
|
* to redirect URLs as well as to general URLs.
|
||||||
|
*/
|
||||||
|
public String encodeRedirectURL(String url) {
|
||||||
|
return encodeURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String encodeUrl(String url) {
|
||||||
|
return encodeURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String encodeRedirectUrl(String url) {
|
||||||
|
return encodeRedirectURL(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendError(int status, String errorMessage) throws IOException {
|
||||||
|
if (isCommitted()) {
|
||||||
|
throw new IllegalStateException("Cannot set error status - response is already committed");
|
||||||
|
}
|
||||||
|
this.status = status;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendError(int status) throws IOException {
|
||||||
|
if (isCommitted()) {
|
||||||
|
throw new IllegalStateException("Cannot set error status - response is already committed");
|
||||||
|
}
|
||||||
|
this.status = status;
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendRedirect(String url) throws IOException {
|
||||||
|
if (isCommitted()) {
|
||||||
|
throw new IllegalStateException("Cannot send redirect - response is already committed");
|
||||||
|
}
|
||||||
|
Assert.notNull(url, "Redirect URL must not be null");
|
||||||
|
this.redirectedUrl = url;
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRedirectedUrl() {
|
||||||
|
return this.redirectedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDateHeader(String name, long value) {
|
||||||
|
setHeaderValue(name, new Long(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addDateHeader(String name, long value) {
|
||||||
|
addHeaderValue(name, new Long(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeader(String name, String value) {
|
||||||
|
setHeaderValue(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addHeader(String name, String value) {
|
||||||
|
addHeaderValue(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIntHeader(String name, int value) {
|
||||||
|
setHeaderValue(name, new Integer(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addIntHeader(String name, int value) {
|
||||||
|
addHeaderValue(name, new Integer(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setHeaderValue(String name, Object value) {
|
||||||
|
doAddHeaderValue(name, value, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addHeaderValue(String name, Object value) {
|
||||||
|
doAddHeaderValue(name, value, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doAddHeaderValue(String name, Object value, boolean replace) {
|
||||||
|
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
|
||||||
|
Assert.notNull(value, "Header value must not be null");
|
||||||
|
if (header == null) {
|
||||||
|
header = new HeaderValueHolder();
|
||||||
|
this.headers.put(name, header);
|
||||||
|
}
|
||||||
|
if (replace) {
|
||||||
|
header.setValue(value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
header.addValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status, String errorMessage) {
|
||||||
|
this.status = status;
|
||||||
|
this.errorMessage = errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return this.status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getErrorMessage() {
|
||||||
|
return this.errorMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
// Methods for MockRequestDispatcher
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
public void setForwardedUrl(String forwardedUrl) {
|
||||||
|
this.forwardedUrl = forwardedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getForwardedUrl() {
|
||||||
|
return this.forwardedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIncludedUrl(String includedUrl) {
|
||||||
|
this.includedUrl = includedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getIncludedUrl() {
|
||||||
|
return this.includedUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner class that adapts the ServletOutputStream to mark the
|
||||||
|
* response as committed once the buffer size is exceeded.
|
||||||
|
*/
|
||||||
|
private class ResponseServletOutputStream extends DelegatingServletOutputStream {
|
||||||
|
|
||||||
|
public ResponseServletOutputStream(OutputStream out) {
|
||||||
|
super(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int b) throws IOException {
|
||||||
|
super.write(b);
|
||||||
|
super.flush();
|
||||||
|
setCommittedIfBufferSizeExceeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() throws IOException {
|
||||||
|
super.flush();
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner class that adapts the PrintWriter to mark the
|
||||||
|
* response as committed once the buffer size is exceeded.
|
||||||
|
*/
|
||||||
|
private class ResponsePrintWriter extends PrintWriter {
|
||||||
|
|
||||||
|
public ResponsePrintWriter(Writer out) {
|
||||||
|
super(out, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(char buf[], int off, int len) {
|
||||||
|
super.write(buf, off, len);
|
||||||
|
super.flush();
|
||||||
|
setCommittedIfBufferSizeExceeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(String s, int off, int len) {
|
||||||
|
super.write(s, off, len);
|
||||||
|
super.flush();
|
||||||
|
setCommittedIfBufferSizeExceeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(int c) {
|
||||||
|
super.write(c);
|
||||||
|
super.flush();
|
||||||
|
setCommittedIfBufferSizeExceeded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void flush() {
|
||||||
|
super.flush();
|
||||||
|
setCommitted(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,245 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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.mock.web;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
import javax.servlet.http.HttpSessionBindingEvent;
|
||||||
|
import javax.servlet.http.HttpSessionBindingListener;
|
||||||
|
import javax.servlet.http.HttpSessionContext;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock implementation of the {@link javax.servlet.http.HttpSession} interface.
|
||||||
|
* Supports the Servlet 2.4 API level.
|
||||||
|
*
|
||||||
|
* <p>Used for testing the web framework; also useful for testing
|
||||||
|
* application controllers.
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @author Rod Johnson
|
||||||
|
* @author Mark Fisher
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
public class MockHttpSession implements HttpSession {
|
||||||
|
|
||||||
|
public static final String SESSION_COOKIE_NAME = "JSESSION";
|
||||||
|
|
||||||
|
private static int nextId = 1;
|
||||||
|
|
||||||
|
|
||||||
|
private final String id;
|
||||||
|
|
||||||
|
private final long creationTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
private int maxInactiveInterval;
|
||||||
|
|
||||||
|
private long lastAccessedTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
private final Hashtable attributes = new Hashtable();
|
||||||
|
|
||||||
|
private boolean invalid = false;
|
||||||
|
|
||||||
|
private boolean isNew = true;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpSession with a default {@link org.springframework.mock.web.MockServletContext}.
|
||||||
|
* @see org.springframework.mock.web.MockServletContext
|
||||||
|
*/
|
||||||
|
public MockHttpSession() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpSession.
|
||||||
|
* @param servletContext the ServletContext that the session runs in
|
||||||
|
*/
|
||||||
|
public MockHttpSession(ServletContext servletContext) {
|
||||||
|
this(servletContext, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockHttpSession.
|
||||||
|
* @param servletContext the ServletContext that the session runs in
|
||||||
|
* @param id a unique identifier for this session
|
||||||
|
*/
|
||||||
|
public MockHttpSession(ServletContext servletContext, String id) {
|
||||||
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
|
this.id = (id != null ? id : Integer.toString(nextId++));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long getCreationTime() {
|
||||||
|
return this.creationTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return this.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void access() {
|
||||||
|
this.lastAccessedTime = System.currentTimeMillis();
|
||||||
|
this.isNew = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastAccessedTime() {
|
||||||
|
return this.lastAccessedTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServletContext getServletContext() {
|
||||||
|
return this.servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxInactiveInterval(int interval) {
|
||||||
|
this.maxInactiveInterval = interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxInactiveInterval() {
|
||||||
|
return this.maxInactiveInterval;
|
||||||
|
}
|
||||||
|
|
||||||
|
public HttpSessionContext getSessionContext() {
|
||||||
|
throw new UnsupportedOperationException("getSessionContext");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getAttribute(String name) {
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
return this.attributes.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getValue(String name) {
|
||||||
|
return getAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getAttributeNames() {
|
||||||
|
return this.attributes.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getValueNames() {
|
||||||
|
return (String[]) this.attributes.keySet().toArray(new String[this.attributes.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttribute(String name, Object value) {
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
if (value != null) {
|
||||||
|
this.attributes.put(name, value);
|
||||||
|
if (value instanceof HttpSessionBindingListener) {
|
||||||
|
((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
removeAttribute(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putValue(String name, Object value) {
|
||||||
|
setAttribute(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAttribute(String name) {
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
Object value = this.attributes.remove(name);
|
||||||
|
if (value instanceof HttpSessionBindingListener) {
|
||||||
|
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeValue(String name) {
|
||||||
|
removeAttribute(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all of this session's attributes.
|
||||||
|
*/
|
||||||
|
public void clearAttributes() {
|
||||||
|
for (Iterator it = this.attributes.entrySet().iterator(); it.hasNext();) {
|
||||||
|
Map.Entry entry = (Map.Entry) it.next();
|
||||||
|
String name = (String) entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
it.remove();
|
||||||
|
if (value instanceof HttpSessionBindingListener) {
|
||||||
|
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invalidate() {
|
||||||
|
this.invalid = true;
|
||||||
|
clearAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInvalid() {
|
||||||
|
return this.invalid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNew(boolean value) {
|
||||||
|
this.isNew = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNew() {
|
||||||
|
return this.isNew;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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() {
|
||||||
|
HashMap state = new HashMap();
|
||||||
|
for (Iterator it = this.attributes.entrySet().iterator(); it.hasNext();) {
|
||||||
|
Map.Entry entry = (Map.Entry) it.next();
|
||||||
|
String name = (String) entry.getKey();
|
||||||
|
Object value = entry.getValue();
|
||||||
|
it.remove();
|
||||||
|
if (value instanceof Serializable) {
|
||||||
|
state.put(name, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Not serializable... Servlet containers usually automatically
|
||||||
|
// unbind the attribute in this case.
|
||||||
|
if (value instanceof HttpSessionBindingListener) {
|
||||||
|
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserialize the attributes of this session from a state object
|
||||||
|
* created by {@link #serializeState()}.
|
||||||
|
* @param state a representation of this session's serialized state
|
||||||
|
*/
|
||||||
|
public void deserializeState(Serializable state) {
|
||||||
|
Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]");
|
||||||
|
this.attributes.putAll((Map) state);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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.mock.web;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.ServletRequest;
|
||||||
|
import javax.servlet.ServletResponse;
|
||||||
|
import javax.servlet.http.HttpServletResponseWrapper;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
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
|
||||||
|
* @since 1.0.2
|
||||||
|
*/
|
||||||
|
public class MockRequestDispatcher implements RequestDispatcher {
|
||||||
|
|
||||||
|
private final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
|
private final String url;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockRequestDispatcher for the given URL.
|
||||||
|
* @param url the URL to dispatch to.
|
||||||
|
*/
|
||||||
|
public MockRequestDispatcher(String url) {
|
||||||
|
Assert.notNull(url, "URL must not be null");
|
||||||
|
this.url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
getMockHttpServletResponse(response).setForwardedUrl(this.url);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void include(ServletRequest request, ServletResponse response) {
|
||||||
|
Assert.notNull(request, "Request must not be null");
|
||||||
|
Assert.notNull(response, "Response must not be null");
|
||||||
|
getMockHttpServletResponse(response).setIncludedUrl(this.url);
|
||||||
|
if (logger.isDebugEnabled()) {
|
||||||
|
logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the underlying MockHttpServletResponse,
|
||||||
|
* unwrapping {@link javax.servlet.http.HttpServletResponseWrapper} decorators if necessary.
|
||||||
|
*/
|
||||||
|
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
|
||||||
|
if (response instanceof MockHttpServletResponse) {
|
||||||
|
return (MockHttpServletResponse) response;
|
||||||
|
}
|
||||||
|
if (response instanceof HttpServletResponseWrapper) {
|
||||||
|
return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse());
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2006 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.mock.web;
|
||||||
|
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import javax.servlet.ServletConfig;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
public class MockServletConfig implements ServletConfig {
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
private final String servletName;
|
||||||
|
|
||||||
|
private final Properties initParameters = new Properties();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletConfig with a default {@link org.springframework.mock.web.MockServletContext}.
|
||||||
|
*/
|
||||||
|
public MockServletConfig() {
|
||||||
|
this(null, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletConfig with a default {@link org.springframework.mock.web.MockServletContext}.
|
||||||
|
* @param servletName the name of the servlet
|
||||||
|
*/
|
||||||
|
public MockServletConfig(String servletName) {
|
||||||
|
this(null, servletName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletConfig.
|
||||||
|
* @param servletContext the ServletContext that the servlet runs in
|
||||||
|
*/
|
||||||
|
public MockServletConfig(ServletContext servletContext) {
|
||||||
|
this(servletContext, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletConfig.
|
||||||
|
* @param servletContext the ServletContext that the servlet runs in
|
||||||
|
* @param servletName the name of the servlet
|
||||||
|
*/
|
||||||
|
public MockServletConfig(ServletContext servletContext, String servletName) {
|
||||||
|
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
|
||||||
|
this.servletName = servletName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getServletName() {
|
||||||
|
return servletName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServletContext getServletContext() {
|
||||||
|
return servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInitParameter(String name, String value) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
this.initParameters.setProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInitParameter(String name) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
return this.initParameters.getProperty(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getInitParameterNames() {
|
||||||
|
return this.initParameters.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,356 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2007 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.mock.web;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Hashtable;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.activation.FileTypeMap;
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
import javax.servlet.Servlet;
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.core.io.DefaultResourceLoader;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ObjectUtils;
|
||||||
|
import org.springframework.web.util.WebUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
|
||||||
|
*
|
||||||
|
* <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 ServletContext, ClassPathXmlApplicationContext or
|
||||||
|
* FileSystemXmlApplicationContext can be used to load the context files for testing,
|
||||||
|
* even for DispatcherServlet context definitions.
|
||||||
|
*
|
||||||
|
* <p>For setting up a full WebApplicationContext in a test environment, you can
|
||||||
|
* use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an
|
||||||
|
* appropriate MockServletContext instance. You might want to configure your
|
||||||
|
* MockServletContext with a FileSystemResourceLoader in that case, to make your
|
||||||
|
* resource paths interpreted as relative file system 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
|
||||||
|
* FileSystemXmlApplicationContext (which will load straight from the file system)
|
||||||
|
* and XmlWebApplicationContext with an underlying MockServletContext (as long as
|
||||||
|
* the MockServletContext has been configured with a FileSystemResourceLoader).
|
||||||
|
*
|
||||||
|
* @author Rod Johnson
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 1.0.2
|
||||||
|
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
|
||||||
|
* @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 {
|
||||||
|
|
||||||
|
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
|
||||||
|
|
||||||
|
|
||||||
|
private final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
|
private final ResourceLoader resourceLoader;
|
||||||
|
|
||||||
|
private final String resourceBasePath;
|
||||||
|
|
||||||
|
private String contextPath = "";
|
||||||
|
|
||||||
|
private final Map contexts = new HashMap();
|
||||||
|
|
||||||
|
private final Properties initParameters = new Properties();
|
||||||
|
|
||||||
|
private final Hashtable attributes = new Hashtable();
|
||||||
|
|
||||||
|
private String servletContextName = "MockServletContext";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletContext, using no base path and a
|
||||||
|
* DefaultResourceLoader (i.e. the classpath root as WAR root).
|
||||||
|
* @see org.springframework.core.io.DefaultResourceLoader
|
||||||
|
*/
|
||||||
|
public MockServletContext() {
|
||||||
|
this("", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletContext, using a DefaultResourceLoader.
|
||||||
|
* @param resourceBasePath the WAR root directory (should not end with a slash)
|
||||||
|
* @see org.springframework.core.io.DefaultResourceLoader
|
||||||
|
*/
|
||||||
|
public MockServletContext(String resourceBasePath) {
|
||||||
|
this(resourceBasePath, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletContext, using the specified ResourceLoader
|
||||||
|
* and no base path.
|
||||||
|
* @param resourceLoader the ResourceLoader to use (or null for the default)
|
||||||
|
*/
|
||||||
|
public MockServletContext(ResourceLoader resourceLoader) {
|
||||||
|
this("", resourceLoader);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new MockServletContext.
|
||||||
|
* @param resourceBasePath the WAR root directory (should not end with a slash)
|
||||||
|
* @param resourceLoader the ResourceLoader to use (or null for the default)
|
||||||
|
*/
|
||||||
|
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
|
||||||
|
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
|
||||||
|
this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : "");
|
||||||
|
|
||||||
|
// Use JVM temp dir as ServletContext temp dir.
|
||||||
|
String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY);
|
||||||
|
if (tempDir != null) {
|
||||||
|
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a full resource location for the given path,
|
||||||
|
* prepending the resource base path of this MockServletContext.
|
||||||
|
* @param path the path as specified
|
||||||
|
* @return the full resource path
|
||||||
|
*/
|
||||||
|
protected String getResourceLocation(String path) {
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
path = "/" + path;
|
||||||
|
}
|
||||||
|
return this.resourceBasePath + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setContextPath(String contextPath) {
|
||||||
|
this.contextPath = (contextPath != null ? contextPath : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a Servlet API 2.5 method. */
|
||||||
|
public String getContextPath() {
|
||||||
|
return this.contextPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerContext(String contextPath, ServletContext context) {
|
||||||
|
this.contexts.put(contextPath, context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServletContext getContext(String contextPath) {
|
||||||
|
if (this.contextPath.equals(contextPath)) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
return (ServletContext) this.contexts.get(contextPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMajorVersion() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinorVersion() {
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMimeType(String filePath) {
|
||||||
|
return MimeTypeResolver.getMimeType(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set getResourcePaths(String path) {
|
||||||
|
String actualPath = (path.endsWith("/") ? path : path + "/");
|
||||||
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
|
||||||
|
try {
|
||||||
|
File file = resource.getFile();
|
||||||
|
String[] fileList = file.list();
|
||||||
|
if (ObjectUtils.isEmpty(fileList)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Set resourcePaths = new LinkedHashSet(fileList.length);
|
||||||
|
for (int i = 0; i < fileList.length; i++) {
|
||||||
|
String resultPath = actualPath + fileList[i];
|
||||||
|
if (resource.createRelative(fileList[i]).getFile().isDirectory()) {
|
||||||
|
resultPath += "/";
|
||||||
|
}
|
||||||
|
resourcePaths.add(resultPath);
|
||||||
|
}
|
||||||
|
return resourcePaths;
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
logger.warn("Couldn't get resource paths for " + resource, ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public URL getResource(String path) throws MalformedURLException {
|
||||||
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
||||||
|
if (!resource.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return resource.getURL();
|
||||||
|
}
|
||||||
|
catch (MalformedURLException ex) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
logger.warn("Couldn't get URL for " + resource, ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getResourceAsStream(String path) {
|
||||||
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
||||||
|
if (!resource.exists()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return resource.getInputStream();
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
logger.warn("Couldn't open InputStream for " + resource, ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDispatcher getRequestDispatcher(String path) {
|
||||||
|
if (!path.startsWith("/")) {
|
||||||
|
throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'");
|
||||||
|
}
|
||||||
|
return new MockRequestDispatcher(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RequestDispatcher getNamedDispatcher(String path) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Servlet getServlet(String name) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getServlets() {
|
||||||
|
return Collections.enumeration(Collections.EMPTY_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getServletNames() {
|
||||||
|
return Collections.enumeration(Collections.EMPTY_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(String message) {
|
||||||
|
logger.info(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(Exception ex, String message) {
|
||||||
|
logger.info(message, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void log(String message, Throwable ex) {
|
||||||
|
logger.info(message, ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRealPath(String path) {
|
||||||
|
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
|
||||||
|
try {
|
||||||
|
return resource.getFile().getAbsolutePath();
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
logger.warn("Couldn't determine real path of resource " + resource, ex);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServerInfo() {
|
||||||
|
return "MockServletContext";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getInitParameter(String name) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
return this.initParameters.getProperty(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInitParameter(String name, String value) {
|
||||||
|
Assert.notNull(name, "Parameter name must not be null");
|
||||||
|
this.initParameters.setProperty(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getInitParameterNames() {
|
||||||
|
return this.initParameters.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getAttribute(String name) {
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
return this.attributes.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Enumeration getAttributeNames() {
|
||||||
|
return this.attributes.keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAttribute(String name, Object value) {
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
if (value != null) {
|
||||||
|
this.attributes.put(name, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.attributes.remove(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeAttribute(String name) {
|
||||||
|
Assert.notNull(name, "Attribute name must not be null");
|
||||||
|
this.attributes.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServletContextName(String servletContextName) {
|
||||||
|
this.servletContextName = servletContextName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getServletContextName() {
|
||||||
|
return this.servletContextName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner factory class used to just introduce a Java Activation Framework
|
||||||
|
* dependency when actually asked to resolve a MIME type.
|
||||||
|
*/
|
||||||
|
private static class MimeTypeResolver {
|
||||||
|
|
||||||
|
public static String getMimeType(String filePath) {
|
||||||
|
return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
|
||||||
|
|
||||||
|
<beans>
|
||||||
|
|
||||||
|
<bean id="index" class="org.springframework.web.servlet.mvc.annotation.IndexController"/>
|
||||||
|
|
||||||
|
<bean id="welcome" class="org.springframework.web.servlet.mvc.annotation.WelcomeController"/>
|
||||||
|
<bean id="admin" class="org.springframework.web.servlet.mvc.annotation.AdminController"/>
|
||||||
|
<bean id="buy" class="org.springframework.web.servlet.mvc.annotation.BuyForm"/>
|
||||||
|
|
||||||
|
<bean name="/myFile" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
|
||||||
|
<bean name="/myFile2" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
|
||||||
|
|
||||||
|
<bean id="mapping" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
|
||||||
|
<!--
|
||||||
|
We have to revert the default exclude for "org.springframework.web.servlet.mvc",
|
||||||
|
since our test controllers sit in this package.
|
||||||
|
-->
|
||||||
|
<property name="excludedPackages"><list></list></property>
|
||||||
|
<property name="excludedClasses" value="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="mapping2" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
|
||||||
|
<!--
|
||||||
|
We have to revert the default exclude for "org.springframework.web.servlet.mvc",
|
||||||
|
since our test controllers sit in this package.
|
||||||
|
-->
|
||||||
|
<property name="excludedPackages"><list></list></property>
|
||||||
|
<property name="excludedClasses" value="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
|
||||||
|
<property name="caseSensitive" value="true"/>
|
||||||
|
<property name="pathPrefix" value="/myapp"/>
|
||||||
|
<property name="basePackage" value="org.springframework.web.servlet"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="mapping3" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
|
||||||
|
<!--
|
||||||
|
We have to revert the default exclude for "org.springframework.web.servlet.mvc",
|
||||||
|
since our test controllers sit in this package.
|
||||||
|
-->
|
||||||
|
<property name="excludedPackages"><list></list></property>
|
||||||
|
<property name="excludedClasses" value="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
|
||||||
|
<property name="caseSensitive" value="true"/>
|
||||||
|
<property name="pathPrefix" value="/myapp"/>
|
||||||
|
<property name="basePackage" value="org.springframework.web.servlet.mvc.annotation"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="mapping4" class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
|
||||||
|
<!--
|
||||||
|
We have to revert the default exclude for "org.springframework.web.servlet.mvc",
|
||||||
|
since our test controllers sit in this package.
|
||||||
|
-->
|
||||||
|
<property name="excludedPackages"><list></list></property>
|
||||||
|
<property name="excludedClasses" value="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
|
||||||
|
<property name="pathPrefix" value="myapp/"/>
|
||||||
|
<property name="basePackage" value=""/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
||||||
Loading…
Reference in New Issue