blob: 88846672044f21bbe781bd55db5702a98ccf90f9 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.struts2.dispatcher;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.LocalizedTextProvider;
import com.opensymphony.xwork2.ObjectFactory;
import com.opensymphony.xwork2.StubValueStack;
import com.opensymphony.xwork2.config.ConfigurationException;
import com.opensymphony.xwork2.config.ConfigurationManager;
import com.opensymphony.xwork2.config.entities.InterceptorMapping;
import com.opensymphony.xwork2.config.entities.InterceptorStackConfig;
import com.opensymphony.xwork2.config.entities.PackageConfig;
import com.opensymphony.xwork2.inject.Container;
import com.opensymphony.xwork2.inject.ContainerBuilder;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.mock.MockActionInvocation;
import com.opensymphony.xwork2.mock.MockActionProxy;
import com.opensymphony.xwork2.test.StubConfigurationProvider;
import com.opensymphony.xwork2.util.location.LocatableProperties;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.StrutsConstants;
import org.apache.struts2.StrutsJUnit4InternalTestCase;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
import org.apache.struts2.util.ObjectFactoryDestroyable;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.mock.web.MockServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Collections.emptyMap;
import static java.util.Collections.singletonMap;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Test case for Dispatcher.
*/
public class DispatcherTest extends StrutsJUnit4InternalTestCase {
@Test
public void testDefaultResourceBundlePropertyLoaded() {
LocalizedTextProvider localizedTextProvider = container.getInstance(LocalizedTextProvider.class);
// some i18n messages from xwork-messages.properties
assertEquals(localizedTextProvider.findDefaultText("xwork.error.action.execution", Locale.US),
"Error during Action invocation");
// some i18n messages from struts-messages.properties
assertEquals(localizedTextProvider.findDefaultText("struts.messages.error.uploading", Locale.US,
new Object[]{"some error messages"}),
"Error uploading: some error messages");
}
@Test
public void testPrepareSetEncodingProperly() {
HttpServletRequest req = new MockHttpServletRequest();
HttpServletResponse res = new MockHttpServletResponse();
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name()));
dispatcher.prepare(req, res);
assertEquals(req.getCharacterEncoding(), UTF_8.name());
assertEquals(res.getCharacterEncoding(), UTF_8.name());
}
@Test
public void testEncodingForXMLHttpRequest() {
// given
MockHttpServletRequest req = new MockHttpServletRequest();
req.addHeader("X-Requested-With", "XMLHttpRequest");
req.setCharacterEncoding(UTF_8.name());
HttpServletResponse res = new MockHttpServletResponse();
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, StandardCharsets.ISO_8859_1.name()));
// when
dispatcher.prepare(req, res);
// then
assertEquals(req.getCharacterEncoding(), UTF_8.name());
assertEquals(res.getCharacterEncoding(), UTF_8.name());
}
@Test
public void testSetEncodingIfDiffer() {
// given
HttpServletRequest req = mock(HttpServletRequest.class);
when(req.getCharacterEncoding()).thenReturn(UTF_8.name());
when(req.getHeader("X-Requested-With")).thenReturn("");
HttpServletResponse res = new MockHttpServletResponse();
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name()));
// when
dispatcher.prepare(req, res);
// then
assertEquals(UTF_8.name(), req.getCharacterEncoding());
assertEquals(UTF_8.name(), res.getCharacterEncoding());
}
@Test
public void testPrepareSetEncodingPropertyWithMultipartRequest() {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
req.setContentType("multipart/form-data");
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name()));
dispatcher.prepare(req, res);
assertEquals(UTF_8.name(), req.getCharacterEncoding());
assertEquals(UTF_8.name(), res.getCharacterEncoding());
}
@Test
public void testPrepareMultipartRequest() throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
req.setMethod("post");
req.setContentType("multipart/form-data; boundary=asdcvb345asd");
dispatcher.prepare(req, res);
assertTrue(dispatcher.wrapRequest(req) instanceof MultiPartRequestWrapper);
}
@Test
public void testPrepareMultipartRequestAllAllowedCharacters() throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
req.setMethod("post");
req.setContentType("multipart/form-data; boundary=01=23a.bC:D((e)d'z?p+o_r,e-");
dispatcher.prepare(req, res);
assertTrue(dispatcher.wrapRequest(req) instanceof MultiPartRequestWrapper);
}
@Test
public void testPrepareMultipartRequestIllegalCharacter() throws Exception {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse res = new MockHttpServletResponse();
req.setMethod("post");
req.setContentType("multipart/form-data; boundary=01=2;3a.bC:D((e)d'z?p+o_r,e-");
dispatcher.prepare(req, res);
assertFalse(dispatcher.wrapRequest(req) instanceof MultiPartRequestWrapper);
}
@Test
public void testDispatcherListener() {
final DispatcherListenerState state = new DispatcherListenerState();
Dispatcher.addDispatcherListener(new DispatcherListener() {
public void dispatcherDestroyed(Dispatcher du) {
state.isDestroyed = true;
}
public void dispatcherInitialized(Dispatcher du) {
state.isInitialized = true;
}
});
assertFalse(state.isDestroyed);
assertFalse(state.isInitialized);
dispatcher.init();
assertTrue(state.isInitialized);
dispatcher.cleanup();
assertTrue(state.isDestroyed);
}
@Test
public void testConfigurationManager() {
configurationManager = spy(new ConfigurationManager(Container.DEFAULT_NAME));
dispatcher = spyDispatcherWithConfigurationManager(new Dispatcher(new MockServletContext(), emptyMap()), configurationManager);
dispatcher.init();
verify(configurationManager, never()).destroyConfiguration();
dispatcher.cleanup();
verify(configurationManager).destroyConfiguration();
}
@Test
public void testInitLoadsDefaultConfig() {
assertNotNull(configuration);
Set<String> expected = new HashSet<>();
expected.add("struts-default.xml");
expected.add("struts-beans.xml");
expected.add("struts-excluded-classes.xml");
expected.add("struts-plugin.xml");
expected.add("struts.xml");
expected.add("struts-deferred.xml");
assertEquals(expected, configuration.getLoadedFileNames());
assertFalse(configuration.getPackageConfigs().isEmpty());
PackageConfig packageConfig = configuration.getPackageConfig("struts-default");
assertFalse(packageConfig.getInterceptorConfigs().isEmpty());
assertFalse(packageConfig.getResultTypeConfigs().isEmpty());
}
@Test
public void testObjectFactoryDestroy() {
InnerDestroyableObjectFactory destroyedObjectFactory = new InnerDestroyableObjectFactory();
dispatcher.setObjectFactory(destroyedObjectFactory);
assertFalse(destroyedObjectFactory.destroyed);
dispatcher.cleanup();
assertTrue(destroyedObjectFactory.destroyed);
}
@Test
public void testInterceptorDestroy() {
Interceptor mockedInterceptor = mock(Interceptor.class);
InterceptorMapping interceptorMapping = new InterceptorMapping("test", mockedInterceptor);
InterceptorStackConfig isc = new InterceptorStackConfig.Builder("test").addInterceptor(interceptorMapping).build();
PackageConfig packageConfig = new PackageConfig.Builder("test").addInterceptorStackConfig(isc).build();
configurationManager = spy(new ConfigurationManager(Container.DEFAULT_NAME));
dispatcher = spyDispatcherWithConfigurationManager(new Dispatcher(new MockServletContext(), emptyMap()), configurationManager);
dispatcher.init();
configuration = spy(configurationManager.getConfiguration());
configurationManager.setConfiguration(configuration);
when(configuration.getPackageConfigs()).thenReturn(singletonMap("test", packageConfig));
dispatcher.cleanup();
verify(mockedInterceptor).destroy();
verify(configuration).destroy();
}
@Test
public void testMultipartSupportEnabledByDefault() {
HttpServletRequest req = new MockHttpServletRequest();
HttpServletResponse res = new MockHttpServletResponse();
dispatcher.prepare(req, res);
assertTrue(dispatcher.isMultipartSupportEnabled(req));
}
@Test
public void testIsMultipartRequest() {
MockHttpServletRequest req = new MockHttpServletRequest();
HttpServletResponse res = new MockHttpServletResponse();
req.setMethod("POST");
dispatcher.prepare(req, res);
req.setContentType("multipart/form-data");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data; boundary=---------------------------207103069210263");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data; boundary=---------------------------207103069210263;charset=UTF-8");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data; boundary=---------------------------207103069210263;charset=ISO-8859-1");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data; boundary=---------------------------207103069210263;charset=Windows-1250");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data; boundary=---------------------------207103069210263;charset=US-ASCII");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data; boundary=---------------------------207103069210263;charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data;boundary=---------------------------207103069210263;charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data;boundary=---------------------------207103069210263; charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data;boundary=---------------------------207103069210263 ;charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data;boundary=---------------------------207103069210263 ; charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data ;boundary=---------------------------207103069210263;charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("multipart/form-data ; boundary=---------------------------207103069210263;charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
req.setContentType("Multipart/Form-Data ; boundary=---------------------------207103069210263;charset=UTF-16LE");
assertTrue(dispatcher.isMultipartRequest(req));
}
@Test
public void testServiceActionResumePreviousProxy() throws Exception {
MockActionInvocation mai = new MockActionInvocation();
ActionContext.getContext().withActionInvocation(mai);
MockActionProxy actionProxy = new MockActionProxy();
actionProxy.setInvocation(mai);
mai.setProxy(actionProxy);
mai.setStack(new StubValueStack());
HttpServletRequest req = new MockHttpServletRequest();
req.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, mai.getStack());
assertFalse(actionProxy.isExecutedCalled());
dispatcher.setDevMode("false");
dispatcher.setHandleException("false");
dispatcher.serviceAction(req, null, new ActionMapping());
assertTrue("should execute previous proxy", actionProxy.isExecutedCalled());
}
@Test
public void testServiceActionCreatesNewProxyIfDifferentMapping() throws Exception {
MockActionInvocation mai = new MockActionInvocation();
ActionContext.getContext().withActionInvocation(mai);
MockActionProxy previousActionProxy = new MockActionProxy();
previousActionProxy.setActionName("first-action");
previousActionProxy.setNamespace("namespace1");
previousActionProxy.setInvocation(mai);
mai.setProxy(previousActionProxy);
mai.setStack(new StubValueStack());
HttpServletRequest request = new MockHttpServletRequest();
request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, mai.getStack());
HttpServletResponse response = new MockHttpServletResponse();
assertFalse(previousActionProxy.isExecutedCalled());
ActionMapping newActionMapping = new ActionMapping();
newActionMapping.setName("hello");
dispatcher.serviceAction(request, response, newActionMapping);
assertFalse(previousActionProxy.isExecutedCalled());
}
/**
* Verify proper default (true) handleExceptionState for Dispatcher and that
* it properly reflects a manually configured change to false.
*/
@Test
public void testHandleException() {
assertTrue("Default Dispatcher handleException state not true ?", dispatcher.isHandleException());
initDispatcher(singletonMap(StrutsConstants.STRUTS_HANDLE_EXCEPTION, "false"));
assertFalse("Modified Dispatcher handleException state not false ?", dispatcher.isHandleException());
}
/**
* Verify proper default (false) devMode for Dispatcher and that
* it properly reflects a manually configured change to true.
*/
@Test
public void testDevMode() {
assertFalse("Default Dispatcher devMode state not false ?", dispatcher.isDevMode());
initDispatcher(singletonMap(StrutsConstants.STRUTS_DEVMODE, "true"));
assertTrue("Modified Dispatcher devMode state not true ?", dispatcher.isDevMode());
}
@Test
public void testGetLocale_With_DefaultLocale_FromConfiguration() {
// Given
HttpServletRequest request = mock(HttpServletRequest.class);
MockHttpSession mockHttpSession = new MockHttpSession();
when(request.getCharacterEncoding()).thenReturn(UTF_8.name());
when(request.getHeader("X-Requested-With")).thenReturn("");
when(request.getParameterMap()).thenReturn(emptyMap());
when(request.getSession(anyBoolean())).thenReturn(mockHttpSession);
HttpServletResponse response = new MockHttpServletResponse();
// Not setting a Struts Locale here, so we should receive the default "de_DE" from the test configuration.
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name()));
// When
dispatcher.prepare(request, response);
ActionContext context = ActionContext.of(createTestContextMap(dispatcher, request, response));
// Then
assertEquals(Locale.GERMANY, context.getLocale()); // Expect the Dispatcher defaultLocale value "de_DE" from the test configuration.
}
@Test
public void testGetLocale_With_DefaultLocale_fr_CA() {
// Given
HttpServletRequest request = mock(HttpServletRequest.class);
MockHttpSession mockHttpSession = new MockHttpSession();
when(request.getCharacterEncoding()).thenReturn(UTF_8.name());
when(request.getHeader("X-Requested-With")).thenReturn("");
when(request.getParameterMap()).thenReturn(emptyMap());
when(request.getSession(anyBoolean())).thenReturn(mockHttpSession);
HttpServletResponse response = new MockHttpServletResponse();
initDispatcher(new HashMap<String, String>() {{
put(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name());
put(StrutsConstants.STRUTS_LOCALE, Locale.CANADA_FRENCH.toString()); // Set the Dispatcher defaultLocale to fr_CA.
}});
// When
dispatcher.prepare(request, response);
ActionContext context = ActionContext.of(createTestContextMap(dispatcher, request, response));
// Then
assertEquals(Locale.CANADA_FRENCH, context.getLocale()); // Expect the Dispatcher defaultLocale value.
}
@Test
public void testGetLocale_With_BadDefaultLocale_RequestLocale_en_UK() {
// Given
HttpServletRequest request = mock(HttpServletRequest.class);
MockHttpSession mockHttpSession = new MockHttpSession();
when(request.getCharacterEncoding()).thenReturn(UTF_8.name());
when(request.getHeader("X-Requested-With")).thenReturn("");
when(request.getParameterMap()).thenReturn(emptyMap());
when(request.getSession(anyBoolean())).thenReturn(mockHttpSession);
when(request.getLocale()).thenReturn(Locale.UK);
HttpServletResponse response = new MockHttpServletResponse();
initDispatcher(new HashMap<String, String>() {{
put(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name());
put(StrutsConstants.STRUTS_LOCALE, "This_is_not_a_valid_Locale_string"); // Set Dispatcher defaultLocale to an invalid value.
}});
// When
dispatcher.prepare(request, response);
ActionContext context = ActionContext.of(createTestContextMap(dispatcher, request, response));
// Then
assertEquals(Locale.UK, context.getLocale()); // Expect the request set value from Mock.
}
@Test
public void testGetLocale_With_BadDefaultLocale_And_RuntimeException() {
// Given
HttpServletRequest request = mock(HttpServletRequest.class);
MockHttpSession mockHttpSession = new MockHttpSession();
when(request.getCharacterEncoding()).thenReturn(UTF_8.name());
when(request.getHeader("X-Requested-With")).thenReturn("");
when(request.getParameterMap()).thenReturn(emptyMap());
when(request.getSession(anyBoolean())).thenReturn(mockHttpSession);
when(request.getLocale()).thenReturn(Locale.UK);
HttpServletResponse response = new MockHttpServletResponse();
initDispatcher(new HashMap<String, String>() {{
put(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name());
put(StrutsConstants.STRUTS_LOCALE, "This_is_not_a_valid_Locale_string"); // Set the Dispatcher defaultLocale to an invalid value.
}});
// When
dispatcher.prepare(request, response);
when(request.getLocale()).thenThrow(new IllegalStateException("Test theoretical state preventing HTTP Request Locale access"));
ActionContext context = ActionContext.of(createTestContextMap(dispatcher, request, response));
// Then
assertEquals(Locale.getDefault(), context.getLocale()); // Expect the system default value, when BOTH Dispatcher default Locale AND request access fail.
}
@Test
public void testGetLocale_With_NullDefaultLocale() {
// Given
HttpServletRequest request = mock(HttpServletRequest.class);
MockHttpSession mockHttpSession = new MockHttpSession();
when(request.getCharacterEncoding()).thenReturn(UTF_8.name());
when(request.getHeader("X-Requested-With")).thenReturn("");
when(request.getParameterMap()).thenReturn(emptyMap());
when(request.getSession(anyBoolean())).thenReturn(mockHttpSession);
when(request.getLocale()).thenReturn(Locale.CANADA_FRENCH);
HttpServletResponse response = new MockHttpServletResponse();
// Attempting to set StrutsConstants.STRUTS_LOCALE to null here via parameters causes an NPE.
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name()));
dispatcher.setDefaultLocale(null); // Force a null Struts default locale, otherwise we receive the default "de_DE" from the test configuration.
// When
dispatcher.prepare(request, response);
ActionContext context = ActionContext.of(createTestContextMap(dispatcher, request, response));
// Then
assertEquals(Locale.CANADA_FRENCH, context.getLocale()); // Expect the request set value from Mock.
}
@Test
public void testGetLocale_With_NullDefaultLocale_And_RuntimeException() {
// Given
HttpServletRequest request = mock(HttpServletRequest.class);
MockHttpSession mockHttpSession = new MockHttpSession();
when(request.getCharacterEncoding()).thenReturn(UTF_8.name());
when(request.getHeader("X-Requested-With")).thenReturn("");
when(request.getParameterMap()).thenReturn(emptyMap());
when(request.getSession(anyBoolean())).thenReturn(mockHttpSession);
when(request.getLocale()).thenReturn(Locale.CANADA_FRENCH);
HttpServletResponse response = new MockHttpServletResponse();
// Attempting to set StrutsConstants.STRUTS_LOCALE to null via parameters causes an NPE.
initDispatcher(singletonMap(StrutsConstants.STRUTS_I18N_ENCODING, UTF_8.name()));
dispatcher.setDefaultLocale(null); // Force a null Struts default locale, otherwise we receive the default "de_DE" from the test configuration.
// When
dispatcher.prepare(request, response);
when(request.getLocale()).thenThrow(new IllegalStateException("Test theoretical state preventing HTTP Request Locale access"));
ActionContext context = ActionContext.of(createTestContextMap(dispatcher, request, response));
// Then
assertEquals(Locale.getDefault(), context.getLocale()); // Expect the system default value when Mock request access fails.
}
@Test
public void dispatcherReinjectedAfterReload() {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
dispatcher.prepare(request, response);
assertEquals(Locale.GERMANY, dispatcher.getLocale(request));
configurationManager.addContainerProvider(new StubConfigurationProvider() {
@Override
public void register(ContainerBuilder builder,
LocatableProperties props) throws ConfigurationException {
props.setProperty(StrutsConstants.STRUTS_LOCALE, "fr_CA");
}
});
configurationManager.reload();
dispatcher.cleanUpRequest(request);
dispatcher.prepare(request, response);
assertEquals(Locale.CANADA_FRENCH, dispatcher.getLocale(request));
}
public static Dispatcher spyDispatcherWithConfigurationManager(Dispatcher dispatcher, ConfigurationManager configurationManager) {
Dispatcher spiedDispatcher = spy(dispatcher);
doReturn(configurationManager).when(spiedDispatcher).createConfigurationManager(any());
return spiedDispatcher;
}
/**
* Create a test context Map from a Dispatcher instance.
* <p>
* The method directly calls getParameterMap() and getSession(true) on the HttpServletRequest.
* <p>
* The method indirectly calls getLocale(request) on the Dispatcher instance, allowing a test of that code path.
* The derived Struts Dispatcher Locale can be retrieved from the Map afterwards.
*/
protected static Map<String, Object> createTestContextMap(Dispatcher dispatcher,
HttpServletRequest request, HttpServletResponse response) {
if (dispatcher == null) {
throw new IllegalArgumentException("Cannot create a test ContextMap from a null Dispatcher");
}
if (request == null) {
throw new IllegalArgumentException("Cannot create a test ContextMap from a null HttpServletRequest");
}
if (response == null) {
throw new IllegalArgumentException("Cannot create a test ContextMap from a null HttpServletResponse");
}
return dispatcher.createContextMap(new RequestMap(request),
HttpParameters.create(request.getParameterMap()).build(),
new SessionMap(request),
new ApplicationMap(request.getSession(true).getServletContext()),
request,
response);
}
static class DispatcherListenerState {
public boolean isInitialized = false;
public boolean isDestroyed = false;
}
public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable {
public boolean destroyed = false;
public InnerDestroyableObjectFactory() {
}
public void destroy() {
destroyed = true;
}
}
}