mirror of
https://github.com/apache/struts.git
synced 2026-08-11 09:36:57 +00:00
WW-4518 Drops FilterDispatcher
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
<filter>
|
||||
<filter-name>action2</filter-name>
|
||||
<filter-class>
|
||||
org.apache.struts2.dispatcher.FilterDispatcher
|
||||
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|
||||
</filter-class>
|
||||
</filter>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<filter>
|
||||
<filter-name>action2</filter-name>
|
||||
<filter-class>
|
||||
org.apache.struts2.dispatcher.FilterDispatcher
|
||||
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|
||||
</filter-class>
|
||||
</filter>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<filter>
|
||||
<filter-name>action2</filter-name>
|
||||
<filter-class>
|
||||
org.apache.struts2.dispatcher.FilterDispatcher
|
||||
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|
||||
</filter-class>
|
||||
</filter>
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
/**
|
||||
* This singleton holds an instance of the web servlet context.
|
||||
* <p/>
|
||||
* This is needed for running Struts on Weblogic Server 6.1
|
||||
* because there is no provision to retrieve the servlet context
|
||||
* from the web session object.
|
||||
* <p/>
|
||||
* This class is created to bet that this singleton can be set by
|
||||
* {@link org.apache.struts2.dispatcher.FilterDispatcherCompatWeblogic61}
|
||||
* before the servlet context is needed by
|
||||
* {@link org.apache.struts2.lifecycle.SessionLifecycleListener}
|
||||
* which will use this object to get it.
|
||||
*
|
||||
*/
|
||||
public class ServletContextSingleton {
|
||||
/**
|
||||
* The web servlet context. Holding this is the
|
||||
* purpose of this singleton.
|
||||
*/
|
||||
private ServletContext servletContext;
|
||||
|
||||
/**
|
||||
* The sole instance of this class.
|
||||
*/
|
||||
private static ServletContextSingleton singleton;
|
||||
|
||||
/**
|
||||
* Constructor which cannot be called
|
||||
* publicly.
|
||||
*/
|
||||
private ServletContextSingleton() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Answers the singleton.
|
||||
* <p/>
|
||||
* At some point, the caller must populate the web servlet
|
||||
* context.
|
||||
*
|
||||
* @return Answers the singleton instance of this class
|
||||
*/
|
||||
public static ServletContextSingleton getInstance() {
|
||||
if (singleton == null) {
|
||||
singleton = new ServletContextSingleton();
|
||||
}
|
||||
return singleton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the servlet context
|
||||
*
|
||||
* @return The web servlet context
|
||||
*/
|
||||
public ServletContext getServletContext() {
|
||||
return servletContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the servlet context
|
||||
*
|
||||
* @param context The web servlet context
|
||||
*/
|
||||
public void setServletContext(ServletContext context) {
|
||||
servletContext = context;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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.util.profiling.UtilTimerStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <!-- SNIPPET START: description -->
|
||||
* Special filter designed to work with the {@link FilterDispatcher} and allow
|
||||
* for easier integration with SiteMesh. Normally, ordering your filters to have
|
||||
* SiteMesh go first, and then {@link FilterDispatcher} go second is perfectly fine.
|
||||
* However, sometimes you may wish to access Struts features, including the
|
||||
* value stack, from within your SiteMesh decorators. Because {@link FilterDispatcher}
|
||||
* cleans up the {@link ActionContext}, your decorator won't have access to the
|
||||
* data you want.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* By adding this filter, the {@link FilterDispatcher} will know to not clean up and
|
||||
* instead defer cleanup to this filter. The ordering of the filters should then be:
|
||||
* <p/>
|
||||
* <ul>
|
||||
* <li>this filter</li>
|
||||
* <li>SiteMesh filter</li>
|
||||
* <li>{@link FilterDispatcher}</li>
|
||||
* </ul>
|
||||
* <!-- SNIPPET END: description -->
|
||||
*
|
||||
*
|
||||
* @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter} and
|
||||
* {@link org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter} to use other Servlet filters that need access to
|
||||
* the ActionContext
|
||||
* @see FilterDispatcher
|
||||
* @see Dispatcher
|
||||
* @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter
|
||||
* @see org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter
|
||||
*
|
||||
* @version $Date$ $Id$
|
||||
*/
|
||||
public class ActionContextCleanUp implements Filter {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ActionContextCleanUp.class);
|
||||
|
||||
private static final String COUNTER = "__cleanup_recursion_counter";
|
||||
|
||||
/**
|
||||
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
showDeprecatedWarning();
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
|
||||
String timerKey = "ActionContextCleanUp_doFilter: ";
|
||||
try {
|
||||
UtilTimerStack.push(timerKey);
|
||||
|
||||
try {
|
||||
Integer count = (Integer)request.getAttribute(COUNTER);
|
||||
if (count == null) {
|
||||
count = 1;
|
||||
}
|
||||
else {
|
||||
count = count.intValue() + 1;
|
||||
}
|
||||
request.setAttribute(COUNTER, count);
|
||||
|
||||
//LOG.debug("filtering counter="+count);
|
||||
|
||||
chain.doFilter(request, response);
|
||||
} finally {
|
||||
int counterVal = ((Integer) request.getAttribute(COUNTER));
|
||||
counterVal -= 1;
|
||||
request.setAttribute(COUNTER, counterVal);
|
||||
cleanUp(request);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
UtilTimerStack.pop(timerKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the request of threadlocals if this is the last execution
|
||||
*
|
||||
* @param req The servlet request
|
||||
*/
|
||||
protected static void cleanUp(ServletRequest req) {
|
||||
// should we clean up yet?
|
||||
Integer count = (Integer) req.getAttribute(COUNTER);
|
||||
if (count != null && count > 0 ) {
|
||||
LOG.debug("Skipping cleanup counter: ", count);
|
||||
return;
|
||||
}
|
||||
|
||||
// always dontClean up the thread request, even if an action hasn't been executed
|
||||
ActionContext.setContext(null);
|
||||
Dispatcher.setInstance(null);
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
public void init(FilterConfig arg0) throws ServletException {
|
||||
}
|
||||
|
||||
private void showDeprecatedWarning() {
|
||||
String msg =
|
||||
"\n\n" +
|
||||
"***************************************************************************\n" +
|
||||
"* WARNING!!! *\n" +
|
||||
"* *\n" +
|
||||
"* >>> ActionContextCleanUp <<< is deprecated! Please use the new filters! *\n" +
|
||||
"* *\n" +
|
||||
"* This can be a source of unpredictable problems! *\n" +
|
||||
"* *\n" +
|
||||
"* Please refer to the docs for more details! *\n" +
|
||||
"* http://struts.apache.org/docs/webxml.html *\n" +
|
||||
"* *\n" +
|
||||
"***************************************************************************\n\n";
|
||||
System.out.println(msg);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,8 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsException;
|
||||
import org.apache.struts2.dispatcher.ng.ExecuteOperations;
|
||||
import org.apache.struts2.dispatcher.ng.PrepareOperations;
|
||||
import org.apache.struts2.views.freemarker.FreemarkerManager;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
@@ -53,7 +55,7 @@ public class DefaultDispatcherErrorHandler implements DispatcherErrorHandler {
|
||||
}
|
||||
|
||||
public void handleError(HttpServletRequest request, HttpServletResponse response, int code, Exception e) {
|
||||
Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
|
||||
Boolean devModeOverride = PrepareOperations.getDevModeOverride();
|
||||
if (devModeOverride != null ? devModeOverride : devMode) {
|
||||
handleErrorInDevMode(response, code, e);
|
||||
} else {
|
||||
|
||||
@@ -1,460 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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.config.Configuration;
|
||||
import com.opensymphony.xwork2.config.ConfigurationProvider;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import com.opensymphony.xwork2.util.ClassLoaderUtil;
|
||||
import com.opensymphony.xwork2.util.ValueStack;
|
||||
import com.opensymphony.xwork2.util.ValueStackFactory;
|
||||
import com.opensymphony.xwork2.util.logging.LoggerFactory;
|
||||
import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.RequestUtils;
|
||||
import org.apache.struts2.StrutsStatics;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.dispatcher.ng.filter.FilterHostConfig;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Master filter for Struts that handles four distinct
|
||||
* responsibilities:
|
||||
* <p/>
|
||||
* <ul>
|
||||
* <p/>
|
||||
* <li>Executing actions</li>
|
||||
* <p/>
|
||||
* <li>Cleaning up the {@link ActionContext} (see note)</li>
|
||||
* <p/>
|
||||
* <li>Serving static content</li>
|
||||
* <p/>
|
||||
* <li>Kicking off XWork's interceptor chain for the request lifecycle</li>
|
||||
* <p/>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* <p/> <b>IMPORTANT</b>: this filter must be mapped to all requests. Unless you know exactly what you are doing, always
|
||||
* map to this URL pattern: /*
|
||||
* <p/>
|
||||
* <p/> <b>Executing actions</b>
|
||||
* <p/>
|
||||
* <p/> This filter executes actions by consulting the {@link ActionMapper} and determining if the requested URL should
|
||||
* invoke an action. If the mapper indicates it should, <b>the rest of the filter chain is stopped</b> and the action is
|
||||
* invoked. This is important, as it means that filters like the SiteMesh filter must be placed <b>before</b> this
|
||||
* filter or they will not be able to decorate the output of actions.
|
||||
* <p/>
|
||||
* <p/> <b>Cleaning up the {@link ActionContext}</b>
|
||||
* <p/>
|
||||
* <p/> This filter will also automatically clean up the {@link ActionContext} for you, ensuring that no memory leaks
|
||||
* take place. However, this can sometimes cause problems integrating with other products like SiteMesh. See {@link
|
||||
* ActionContextCleanUp} for more information on how to deal with this.
|
||||
* <p/>
|
||||
* <p/> <b>Serving static content</b>
|
||||
* <p/>
|
||||
* <p/> This filter also serves common static content needed when using various parts of Struts, such as JavaScript
|
||||
* files, CSS files, etc. It works by looking for requests to /struts/*, and then mapping the value after "/struts/"
|
||||
* to common packages in Struts and, optionally, in your class path. By default, the following packages are
|
||||
* automatically searched:
|
||||
* <p/>
|
||||
* <ul>
|
||||
* <p/>
|
||||
* <li>org.apache.struts2.static</li>
|
||||
* <p/>
|
||||
* <li>template</li>
|
||||
* <p/>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* <p/> This means that you can simply request /struts/xhtml/styles.css and the XHTML UI theme's default stylesheet
|
||||
* will be returned. Likewise, many of the AJAX UI components require various JavaScript files, which are found in the
|
||||
* org.apache.struts2.static package. If you wish to add additional packages to be searched, you can add a comma
|
||||
* separated (space, tab and new line will do as well) list in the filter init parameter named "packages". <b>Be
|
||||
* careful</b>, however, to expose any packages that may have sensitive information, such as properties file with
|
||||
* database access credentials.
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p/>
|
||||
* <p>
|
||||
* <p/>
|
||||
* This filter supports the following init-params:
|
||||
* <!-- START SNIPPET: params -->
|
||||
* <p/>
|
||||
* <ul>
|
||||
* <p/>
|
||||
* <li><b>config</b> - a comma-delimited list of XML configuration files to load.</li>
|
||||
* <p/>
|
||||
* <li><b>actionPackages</b> - a comma-delimited list of Java packages to scan for Actions.</li>
|
||||
* <p/>
|
||||
* <li><b>configProviders</b> - a comma-delimited list of Java classes that implement the
|
||||
* {@link ConfigurationProvider} interface that should be used for building the {@link Configuration}.</li>
|
||||
* <p/>
|
||||
* <li><b>loggerFactory</b> - The class name of the {@link LoggerFactory} implementation.</li>
|
||||
* <p/>
|
||||
* <li><b>*</b> - any other parameters are treated as framework constants.</li>
|
||||
* <p/>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* <!-- END SNIPPET: params -->
|
||||
* <p/>
|
||||
* </p>
|
||||
* <p/>
|
||||
* To use a custom {@link Dispatcher}, the <code>createDispatcher()</code> method could be overriden by
|
||||
* the subclass.
|
||||
*
|
||||
* @version $Date$ $Id$
|
||||
* @deprecated Since Struts 2.1.3, use {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter} instead or
|
||||
* {@link org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter} and {@link org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter}
|
||||
* if needing using the {@link ActionContextCleanUp} filter in addition to this one
|
||||
*
|
||||
* @see ActionMapper
|
||||
* @see ActionContextCleanUp
|
||||
* @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
|
||||
* @see org.apache.struts2.dispatcher.ng.filter.StrutsPrepareFilter
|
||||
* @see org.apache.struts2.dispatcher.ng.filter.StrutsExecuteFilter
|
||||
*/
|
||||
public class FilterDispatcher implements StrutsStatics, Filter {
|
||||
|
||||
/**
|
||||
* Provide a logging instance.
|
||||
*/
|
||||
private Logger log;
|
||||
|
||||
/**
|
||||
* Provide ActionMapper instance, set by injection.
|
||||
*/
|
||||
private ActionMapper actionMapper;
|
||||
|
||||
/**
|
||||
* Provide FilterConfig instance, set on init.
|
||||
*/
|
||||
private FilterConfig filterConfig;
|
||||
|
||||
/**
|
||||
* Expose Dispatcher instance to subclass.
|
||||
*/
|
||||
protected Dispatcher dispatcher;
|
||||
|
||||
/**
|
||||
* Loads static resources, set by injection.
|
||||
*/
|
||||
protected StaticContentLoader staticResourceLoader;
|
||||
|
||||
/**
|
||||
* Maintains per-request override of devMode configuration.
|
||||
*/
|
||||
private static ThreadLocal<Boolean> devModeOverride = new InheritableThreadLocal<>();
|
||||
|
||||
/**
|
||||
* Initializes the filter by creating a default dispatcher
|
||||
* and setting the default packages for static resources.
|
||||
*
|
||||
* @param filterConfig The filter configuration
|
||||
*/
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
try {
|
||||
this.filterConfig = filterConfig;
|
||||
|
||||
initLogging();
|
||||
|
||||
dispatcher = createDispatcher(filterConfig);
|
||||
dispatcher.init();
|
||||
dispatcher.getContainer().inject(this);
|
||||
|
||||
staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
|
||||
} finally {
|
||||
ActionContext.setContext(null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 2.5
|
||||
*/
|
||||
@Deprecated
|
||||
private void initLogging() {
|
||||
String factoryName = filterConfig.getInitParameter("loggerFactory");
|
||||
if (factoryName != null) {
|
||||
try {
|
||||
Class cls = ClassLoaderUtil.loadClass(factoryName, this.getClass());
|
||||
LoggerFactory fac = (LoggerFactory) cls.newInstance();
|
||||
LoggerFactory.setLoggerFactory(fac);
|
||||
} catch (InstantiationException e) {
|
||||
System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default");
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
System.err.println("Unable to access logger factory: " + factoryName + ", using default");
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("Unable to locate logger factory class: " + factoryName + ", using default");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
log = LogManager.getLogger(FilterDispatcher.class);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls dispatcher.cleanup,
|
||||
* which in turn releases local threads and destroys any DispatchListeners.
|
||||
*
|
||||
* @see javax.servlet.Filter#destroy()
|
||||
*/
|
||||
public void destroy() {
|
||||
if (dispatcher == null) {
|
||||
log.warn("something is seriously wrong, Dispatcher is not initialized (null)");
|
||||
} else {
|
||||
try {
|
||||
dispatcher.cleanup();
|
||||
} finally {
|
||||
ActionContext.setContext(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an override of the static devMode value. Do not set this via a
|
||||
* request parameter or any other unprotected method. Using a signed
|
||||
* cookie is one safe way to turn it on per request.
|
||||
*
|
||||
* @param devMode the override value
|
||||
*/
|
||||
public static void overrideDevMode(boolean devMode) {
|
||||
devModeOverride.set(devMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean override value, or null if no override
|
||||
*/
|
||||
public static Boolean getDevModeOverride()
|
||||
{
|
||||
return devModeOverride.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default {@link Dispatcher} that subclasses can override
|
||||
* with a custom Dispatcher, if needed.
|
||||
*
|
||||
* @param filterConfig Our FilterConfig
|
||||
* @return Initialized Dispatcher
|
||||
*/
|
||||
protected Dispatcher createDispatcher(FilterConfig filterConfig) {
|
||||
Map<String, String> params = new HashMap<>();
|
||||
for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements();) {
|
||||
String name = (String) e.nextElement();
|
||||
String value = filterConfig.getInitParameter(name);
|
||||
params.put(name, value);
|
||||
}
|
||||
return createDispatcher(filterConfig.getServletContext(), params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a default {@link Dispatcher} that subclasses can override
|
||||
* with a custom Dispatcher, if needed. Called by
|
||||
* createDispatcher(FilterConfig).
|
||||
*
|
||||
* @param ctx ServletContext
|
||||
* @param params parameters from FilterConfig
|
||||
* @return Initialized Dispatcher
|
||||
*/
|
||||
protected Dispatcher createDispatcher(ServletContext ctx, Map<String, String> params) {
|
||||
return new Dispatcher(ctx, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify state of StrutsConstants.STRUTS_STATIC_CONTENT_LOADER setting.
|
||||
* @param staticResourceLoader val New setting
|
||||
*/
|
||||
@Inject
|
||||
public void setStaticResourceLoader(StaticContentLoader staticResourceLoader) {
|
||||
this.staticResourceLoader = staticResourceLoader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify ActionMapper instance.
|
||||
* @param mapper New instance
|
||||
*/
|
||||
@Inject
|
||||
public void setActionMapper(ActionMapper mapper) {
|
||||
actionMapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a workaround for some versions of WebLogic.
|
||||
* <p/>
|
||||
* Servlet 2.3 specifies that the servlet context can be retrieved from the session. Unfortunately, some versions of
|
||||
* WebLogic can only retrieve the servlet context from the filter config. Hence, this method enables subclasses to
|
||||
* retrieve the servlet context from other sources.
|
||||
*
|
||||
* @return the servlet context.
|
||||
*/
|
||||
protected ServletContext getServletContext() {
|
||||
return filterConfig.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose the FilterConfig instance.
|
||||
*
|
||||
* @return Our FilterConfit instance
|
||||
*/
|
||||
protected FilterConfig getFilterConfig() {
|
||||
return filterConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap and return the given request, if needed, so as to to transparently
|
||||
* handle multipart data as a wrapped class around the given request.
|
||||
*
|
||||
* @param request Our ServletRequest object
|
||||
* @param response Our ServerResponse object
|
||||
* @return Wrapped HttpServletRequest object
|
||||
* @throws ServletException on any error
|
||||
*/
|
||||
protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException {
|
||||
|
||||
Dispatcher du = Dispatcher.getInstance();
|
||||
|
||||
// Prepare and wrap the request if the cleanup filter hasn't already, cleanup filter should be
|
||||
// configured first before struts2 dispatcher filter, hence when its cleanup filter's turn,
|
||||
// static instance of Dispatcher should be null.
|
||||
if (du == null) {
|
||||
|
||||
Dispatcher.setInstance(dispatcher);
|
||||
|
||||
// prepare the request no matter what - this ensures that the proper character encoding
|
||||
// is used before invoking the mapper (see WW-9127)
|
||||
dispatcher.prepare(request, response);
|
||||
} else {
|
||||
dispatcher = du;
|
||||
}
|
||||
|
||||
try {
|
||||
// Wrap request first, just in case it is multipart/form-data
|
||||
// parameters might not be accessible through before encoding (ww-1278)
|
||||
request = dispatcher.wrapRequest(request);
|
||||
} catch (IOException e) {
|
||||
String message = "Could not wrap servlet request with MultipartRequestWrapper!";
|
||||
log.error(message, e);
|
||||
throw new ServletException(message, e);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process an action or handle a request a static resource.
|
||||
* <p/>
|
||||
* The filter tries to match the request to an action mapping.
|
||||
* If mapping is found, the action processes is delegated to the dispatcher's serviceAction method.
|
||||
* If action processing fails, doFilter will try to create an error page via the dispatcher.
|
||||
* <p/>
|
||||
* Otherwise, if the request is for a static resource,
|
||||
* the resource is copied directly to the response, with the appropriate caching headers set.
|
||||
* <p/>
|
||||
* If the request does not match an action mapping, or a static resource page,
|
||||
* then it passes through.
|
||||
*
|
||||
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
|
||||
*/
|
||||
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
|
||||
|
||||
showDeprecatedWarning();
|
||||
|
||||
HttpServletRequest request = (HttpServletRequest) req;
|
||||
HttpServletResponse response = (HttpServletResponse) res;
|
||||
ServletContext servletContext = getServletContext();
|
||||
|
||||
String timerKey = "FilterDispatcher_doFilter: ";
|
||||
try {
|
||||
|
||||
// FIXME: this should be refactored better to not duplicate work with the action invocation
|
||||
ValueStack stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
|
||||
ActionContext ctx = new ActionContext(stack.getContext());
|
||||
ActionContext.setContext(ctx);
|
||||
|
||||
UtilTimerStack.push(timerKey);
|
||||
request = prepareDispatcherAndWrapRequest(request, response);
|
||||
ActionMapping mapping;
|
||||
try {
|
||||
mapping = actionMapper.getMapping(request, dispatcher.getConfigurationManager());
|
||||
} catch (Exception ex) {
|
||||
log.error("error getting ActionMapping", ex);
|
||||
dispatcher.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mapping == null) {
|
||||
// there is no action in this request, should we look for a static resource?
|
||||
String resourcePath = RequestUtils.getServletPath(request);
|
||||
|
||||
if ("".equals(resourcePath) && null != request.getPathInfo()) {
|
||||
resourcePath = request.getPathInfo();
|
||||
}
|
||||
|
||||
if (staticResourceLoader.canHandle(resourcePath)) {
|
||||
staticResourceLoader.findStaticResource(resourcePath, request, response);
|
||||
} else {
|
||||
// this is a normal request, let it pass through
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
// The framework did its job here
|
||||
return;
|
||||
}
|
||||
|
||||
dispatcher.serviceAction(request, response, mapping);
|
||||
|
||||
} finally {
|
||||
dispatcher.cleanUpRequest(request);
|
||||
try {
|
||||
ActionContextCleanUp.cleanUp(req);
|
||||
} finally {
|
||||
UtilTimerStack.pop(timerKey);
|
||||
}
|
||||
devModeOverride.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private void showDeprecatedWarning() {
|
||||
String msg =
|
||||
"\n\n" +
|
||||
"***********************************************************************\n" +
|
||||
"* WARNING!!! *\n" +
|
||||
"* *\n" +
|
||||
"* >>> FilterDispatcher <<< is deprecated! Please use the new filters! *\n" +
|
||||
"* *\n" +
|
||||
"* This can be a source of unpredictable problems! *\n" +
|
||||
"* *\n" +
|
||||
"* Please refer to the docs for more details! *\n" +
|
||||
"* http://struts.apache.org/docs/webxml.html *\n" +
|
||||
"* *\n" +
|
||||
"***********************************************************************\n\n";
|
||||
System.out.println(msg);
|
||||
}
|
||||
}
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 javax.servlet.Filter;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.apache.struts2.config.ServletContextSingleton;
|
||||
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
|
||||
/**
|
||||
* When running Weblogic Server 6.1, this class should be
|
||||
* specified in web.xml instead of {@link FilterDispatcher}.
|
||||
* <p/>
|
||||
* This class properly handles the weblogic.jar handling
|
||||
* of servlet filters. There is one serious incompatibility, and
|
||||
* that is that while {@link FilterDispatcher#init(FilterConfig)}
|
||||
* throws a {@link ServletException}, this class's method
|
||||
* {@link #setFilterConfig(FilterConfig)} does not throw
|
||||
* the exception. Since {@link #setFilterConfig(FilterConfig)}
|
||||
* invokes {@link FilterDispatcher#init(FilterConfig)}, the setter
|
||||
* must "swallow" the exception. This it does by logging the
|
||||
* exception as an error.
|
||||
*
|
||||
* @deprecated Since Struts 2.1.3 as it probably isn't used anymore
|
||||
*
|
||||
*/
|
||||
public class FilterDispatcherCompatWeblogic61 extends FilterDispatcher {
|
||||
|
||||
private static Logger LOG = LogManager.getLogger(FilterDispatcherCompatWeblogic61.class);
|
||||
|
||||
/**
|
||||
* dummy setter for {@link #filterConfig}; this method
|
||||
* sets up the {@link org.apache.struts2.config.ServletContextSingleton} with
|
||||
* the servlet context from the filter configuration.
|
||||
* <p/>
|
||||
* This is needed by Weblogic Server 6.1 because it
|
||||
* uses a slightly obsolete Servlet 2.3-minus spec
|
||||
* whose {@link Filter} interface requires this method.
|
||||
* <p/>
|
||||
*
|
||||
* @param filterConfig the filter configuration.
|
||||
*/
|
||||
public void setFilterConfig(FilterConfig filterConfig) {
|
||||
try {
|
||||
init(filterConfig);
|
||||
} catch (ServletException se) {
|
||||
LOG.error("Couldn't set the filter configuration in this filter", se);
|
||||
}
|
||||
|
||||
ServletContextSingleton singleton = ServletContextSingleton.getInstance();
|
||||
singleton.setServletContext(filterConfig.getServletContext());
|
||||
}
|
||||
|
||||
/**
|
||||
* answers the servlet context.
|
||||
* <p/>
|
||||
* Servlet 2.3 specifies that this can be retrieved from
|
||||
* the session. Unfortunately, weblogic.jar can only retrieve
|
||||
* the servlet context from the filter config. Hence, this
|
||||
* returns the servlet context from the singleton that was
|
||||
* setup by {@link #setFilterConfig(FilterConfig)}.
|
||||
*
|
||||
* @param session the HTTP session. Not used
|
||||
* @return the servlet context.
|
||||
*/
|
||||
protected ServletContext getServletContext(HttpSession session) {
|
||||
ServletContextSingleton singleton =
|
||||
ServletContextSingleton.getInstance();
|
||||
return singleton.getServletContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is required by Weblogic 6.1 SP4 because
|
||||
* they defined this as a required method just before
|
||||
* the Servlet 2.3 specification was finalized.
|
||||
*
|
||||
* @return the filter's filter configuration
|
||||
*/
|
||||
public FilterConfig getFilterConfig() {
|
||||
return super.getFilterConfig();
|
||||
}
|
||||
}
|
||||
@@ -47,6 +47,12 @@ public class PrepareOperations {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(PrepareOperations.class);
|
||||
|
||||
/**
|
||||
* Maintains per-request override of devMode configuration.
|
||||
*/
|
||||
private static ThreadLocal<Boolean> devModeOverride = new InheritableThreadLocal<>();
|
||||
|
||||
|
||||
private Dispatcher dispatcher;
|
||||
private static final String STRUTS_ACTION_MAPPING_KEY = "struts.actionMapping";
|
||||
public static final String CLEANUP_RECURSION_COUNTER = "__cleanup_recursion_counter";
|
||||
@@ -99,6 +105,7 @@ public class PrepareOperations {
|
||||
} finally {
|
||||
ActionContext.setContext(null);
|
||||
Dispatcher.setInstance(null);
|
||||
devModeOverride.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,4 +207,23 @@ public class PrepareOperations {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an override of the static devMode value. Do not set this via a
|
||||
* request parameter or any other unprotected method. Using a signed
|
||||
* cookie is one safe way to turn it on per request.
|
||||
*
|
||||
* @param devMode the override value
|
||||
*/
|
||||
public static void overrideDevMode(boolean devMode) {
|
||||
devModeOverride.set(devMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Boolean override value, or null if no override
|
||||
*/
|
||||
public static Boolean getDevModeOverride()
|
||||
{
|
||||
return devModeOverride.get();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.FilterDispatcher;
|
||||
import org.apache.struts2.dispatcher.ng.PrepareOperations;
|
||||
import org.apache.struts2.views.freemarker.FreemarkerManager;
|
||||
import org.apache.struts2.views.freemarker.FreemarkerResult;
|
||||
|
||||
@@ -137,7 +137,7 @@ public class DebuggingInterceptor extends AbstractInterceptor {
|
||||
public String intercept(ActionInvocation inv) throws Exception {
|
||||
boolean actionOnly = false;
|
||||
boolean cont = true;
|
||||
Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
|
||||
Boolean devModeOverride = PrepareOperations.getDevModeOverride();
|
||||
boolean devMode = devModeOverride != null ? devModeOverride : this.devMode;
|
||||
if (devMode) {
|
||||
final ActionContext ctx = ActionContext.getContext();
|
||||
|
||||
@@ -26,7 +26,6 @@ package org.apache.struts2.util;
|
||||
* if it requires shutdown hook whenever an ObjectFactory is to be
|
||||
* destroyed.
|
||||
*
|
||||
* @see org.apache.struts2.dispatcher.FilterDispatcher
|
||||
* @see org.apache.struts2.dispatcher.Dispatcher
|
||||
*/
|
||||
public interface ObjectFactoryDestroyable {
|
||||
|
||||
@@ -1,186 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.springframework.mock.web.MockFilterConfig;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
import com.mockobjects.servlet.MockFilterChain;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
/**
|
||||
* @version $Date$ $Id$
|
||||
*/
|
||||
public class ActionContextCleanUpTest extends TestCase {
|
||||
|
||||
|
||||
protected MockFilterConfig filterConfig;
|
||||
protected MockHttpServletRequest request;
|
||||
protected MockHttpServletResponse response;
|
||||
protected MockFilterChain filterChain;
|
||||
protected MockFilterChain filterChain2;
|
||||
protected MockServletContext servletContext;
|
||||
|
||||
protected Counter counter;
|
||||
protected Map<String, Integer> _tmpStore;
|
||||
protected InnerDispatcher _dispatcher;
|
||||
protected InnerDispatcher _dispatcher2;
|
||||
protected ActionContextCleanUp cleanUp;
|
||||
protected ActionContextCleanUp cleanUp2;
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
filterConfig = null;
|
||||
request = null;
|
||||
response = null;
|
||||
filterChain = null;
|
||||
filterChain2 = null;
|
||||
servletContext = null;
|
||||
counter = null;
|
||||
_tmpStore = null;
|
||||
_dispatcher = null;
|
||||
_dispatcher2 = null;
|
||||
cleanUp = null;
|
||||
cleanUp2 = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
Dispatcher.setInstance(null);
|
||||
|
||||
counter = new Counter();
|
||||
_tmpStore = new LinkedHashMap<String, Integer>();
|
||||
|
||||
filterConfig = new MockFilterConfig();
|
||||
request = new MockHttpServletRequest();
|
||||
response = new MockHttpServletResponse();
|
||||
servletContext = new MockServletContext();
|
||||
_dispatcher = new InnerDispatcher(servletContext) {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "dispatcher";
|
||||
}
|
||||
};
|
||||
_dispatcher2 = new InnerDispatcher(servletContext){
|
||||
@Override
|
||||
public String toString() {
|
||||
return "dispatcher2";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
filterChain = new MockFilterChain() {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
|
||||
_tmpStore.put("counter"+(counter.count++), (Integer) request.getAttribute("__cleanup_recursion_counter"));
|
||||
}
|
||||
};
|
||||
|
||||
cleanUp = new ActionContextCleanUp();
|
||||
cleanUp2 = new ActionContextCleanUp();
|
||||
filterChain2 = new MockFilterChain() {
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
|
||||
_tmpStore.put("counter"+(counter.count++), (Integer) request.getAttribute("__cleanup_recursion_counter"));
|
||||
cleanUp2.doFilter(request, response, filterChain);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public void testSingle() throws Exception {
|
||||
assertNull(request.getAttribute("__cleanup_recursion_counter"));
|
||||
|
||||
cleanUp.init(filterConfig);
|
||||
cleanUp.doFilter(request, response, filterChain);
|
||||
cleanUp.destroy();
|
||||
|
||||
assertEquals(_tmpStore.size(), 1);
|
||||
assertEquals(_tmpStore.get("counter0"), new Integer(1));
|
||||
|
||||
assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0"));
|
||||
}
|
||||
|
||||
public void testMultiple() throws Exception {
|
||||
assertNull(request.getAttribute("__cleanup_recursion_counter"));
|
||||
|
||||
cleanUp.init(filterConfig);
|
||||
cleanUp2.init(filterConfig);
|
||||
cleanUp.doFilter(request, response, filterChain2);
|
||||
cleanUp2.destroy();
|
||||
cleanUp.destroy();
|
||||
|
||||
assertEquals(_tmpStore.size(), 2);
|
||||
assertEquals(_tmpStore.get("counter0"), new Integer(1));
|
||||
assertEquals(_tmpStore.get("counter1"), new Integer(2));
|
||||
|
||||
assertEquals(request.getAttribute("__cleanup_recursion_counter"), new Integer("0"));
|
||||
}
|
||||
|
||||
|
||||
class InnerDispatcher extends Dispatcher {
|
||||
public boolean prepare = false;
|
||||
public boolean wrapRequest = false;
|
||||
public boolean service = false;
|
||||
|
||||
public InnerDispatcher(ServletContext servletContext) {
|
||||
super(servletContext, new HashMap<String,String>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(HttpServletRequest request, HttpServletResponse response) {
|
||||
prepare = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
|
||||
wrapRequest = true;
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
|
||||
service = true;
|
||||
}
|
||||
}
|
||||
|
||||
class Counter {
|
||||
public int count=0;
|
||||
}
|
||||
}
|
||||
@@ -35,13 +35,12 @@ import com.opensymphony.xwork2.interceptor.Interceptor;
|
||||
import com.opensymphony.xwork2.util.LocalizedTextUtil;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.dispatcher.FilterDispatcherTest.InnerDestroyableObjectFactory;
|
||||
import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
|
||||
import org.apache.struts2.util.ObjectFactoryDestroyable;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Collections;
|
||||
@@ -273,4 +272,13 @@ public class DispatcherTest extends StrutsInternalTestCase {
|
||||
public boolean isInitialized = false;
|
||||
public boolean isDestroyed = false;
|
||||
}
|
||||
|
||||
public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable {
|
||||
public boolean destroyed = false;
|
||||
|
||||
public void destroy() {
|
||||
destroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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.mockobjects.servlet.MockFilterChain;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.config.ConfigurationManager;
|
||||
import com.opensymphony.xwork2.config.impl.DefaultConfiguration;
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.apache.struts2.util.ObjectFactoryDestroyable;
|
||||
import org.springframework.mock.web.MockFilterConfig;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* FilterDispatcher TestCase.
|
||||
*
|
||||
* @version $Date$ $Id$
|
||||
*/
|
||||
public class FilterDispatcherTest extends StrutsInternalTestCase {
|
||||
|
||||
public void testIfActionMapperIsNullDontServiceAction() throws Exception {
|
||||
MockServletContext servletContext = new MockServletContext();
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(servletContext);
|
||||
MockHttpServletRequest req = new MockHttpServletRequest(servletContext);
|
||||
MockHttpServletResponse res = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
ConfigurationManager confManager = new ConfigurationManager();
|
||||
confManager.setConfiguration(new DefaultConfiguration());
|
||||
|
||||
final NoOpDispatcher _dispatcher = new NoOpDispatcher(servletContext, confManager);
|
||||
Dispatcher.setInstance(_dispatcher);
|
||||
|
||||
|
||||
|
||||
|
||||
FilterDispatcher filter = new FilterDispatcher() {
|
||||
protected Dispatcher createDispatcher() {
|
||||
return _dispatcher;
|
||||
}
|
||||
};
|
||||
filter.init(filterConfig);
|
||||
filter.setActionMapper(null);
|
||||
filter.doFilter(req, res, chain);
|
||||
|
||||
assertFalse(_dispatcher.serviceRequest);
|
||||
}
|
||||
|
||||
public void testCharacterEncodingSetBeforeRequestWrappingAndActionService() throws Exception {
|
||||
MockServletContext servletContext = new MockServletContext();
|
||||
MockFilterConfig filterConfig = new MockFilterConfig(servletContext);
|
||||
MockHttpServletRequest req = new MockHttpServletRequest(servletContext);
|
||||
MockHttpServletResponse res = new MockHttpServletResponse();
|
||||
MockFilterChain chain = new MockFilterChain();
|
||||
final InnerDispatcher _dispatcher = new InnerDispatcher(servletContext);
|
||||
Dispatcher.setInstance(null);
|
||||
|
||||
_dispatcher.setDefaultEncoding("UTF-16_DUMMY");
|
||||
|
||||
FilterDispatcher filter = new FilterDispatcher() {
|
||||
protected Dispatcher createDispatcher(FilterConfig filterConfig) {
|
||||
return _dispatcher;
|
||||
}
|
||||
};
|
||||
filter.init(filterConfig);
|
||||
// set ActionMapper after init() as all dependencies will be injected in init()
|
||||
filter.setActionMapper(new InnerActionMapper());
|
||||
_dispatcher.setDefaultEncoding("UTF-16_DUMMY");
|
||||
filter.doFilter(req, res, chain);
|
||||
|
||||
assertTrue(_dispatcher.wrappedRequest);
|
||||
assertTrue(_dispatcher.serviceRequest);
|
||||
}
|
||||
|
||||
// === inner class ========
|
||||
public static class InnerObjectFactory extends ObjectFactory {
|
||||
|
||||
}
|
||||
|
||||
public static class NoOpDispatcher extends Dispatcher {
|
||||
protected boolean wrappedRequest = false;
|
||||
protected boolean serviceRequest = false;
|
||||
|
||||
public NoOpDispatcher(ServletContext servletContext, ConfigurationManager cm) {
|
||||
super(servletContext, new HashMap());
|
||||
this.configurationManager = cm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
|
||||
wrappedRequest = true;
|
||||
return request;
|
||||
}
|
||||
|
||||
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
|
||||
serviceRequest = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendError(HttpServletRequest request, HttpServletResponse response, int code, Exception e) {
|
||||
// NO-OP
|
||||
}
|
||||
}
|
||||
|
||||
public static class InnerDispatcher extends Dispatcher {
|
||||
|
||||
protected boolean wrappedRequest = false;
|
||||
protected boolean serviceRequest = false;
|
||||
|
||||
public InnerDispatcher(ServletContext servletContext) {
|
||||
super(servletContext, new HashMap());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
|
||||
wrappedRequest = true;
|
||||
// if we set the chracter encoding AFTER we do wrap request, we will get
|
||||
// a failing test
|
||||
assertNotNull(request.getCharacterEncoding());
|
||||
assertEquals("UTF-16_DUMMY", request.getCharacterEncoding());
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
|
||||
serviceRequest = true;
|
||||
// if we set the chracter encoding AFTER we do wrap request, we will get
|
||||
// a failing test
|
||||
assertNotNull(request.getCharacterEncoding());
|
||||
assertEquals("UTF-16_DUMMY", request.getCharacterEncoding());
|
||||
}
|
||||
}
|
||||
|
||||
public static class InnerActionMapper implements ActionMapper {
|
||||
|
||||
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager config) {
|
||||
return new ActionMapping("action", "/", null, Collections.<String, Object>emptyMap());
|
||||
}
|
||||
|
||||
public ActionMapping getMappingFromActionName(String actionName) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public String getUriFromActionMapping(ActionMapping mapping) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NullActionMapper implements ActionMapper {
|
||||
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager config) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ActionMapping getMappingFromActionName(String actionName) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public String getUriFromActionMapping(ActionMapping mapping) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class InnerDestroyableObjectFactory extends ObjectFactory implements ObjectFactoryDestroyable {
|
||||
public boolean destroyed = false;
|
||||
|
||||
public void destroy() {
|
||||
destroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,363 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* 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 java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.struts2.StrutsInternalTestCase;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapper;
|
||||
import org.apache.struts2.dispatcher.mapper.ActionMapping;
|
||||
import org.springframework.mock.web.MockFilterConfig;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
|
||||
import com.mockobjects.servlet.MockFilterChain;
|
||||
import com.opensymphony.xwork2.ObjectFactory;
|
||||
import com.opensymphony.xwork2.config.ConfigurationManager;
|
||||
import com.opensymphony.xwork2.inject.Container;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @version $Date$ $Id$
|
||||
*/
|
||||
public class FilterTest extends StrutsInternalTestCase {
|
||||
|
||||
protected MockFilterConfig filterConfig;
|
||||
protected MockHttpServletRequest request;
|
||||
protected MockHttpServletResponse response;
|
||||
protected MockFilterChain filterChain;
|
||||
protected MockFilterChain filterChain2;
|
||||
protected MockServletContext servletContext;
|
||||
|
||||
protected InnerDispatcher _dispatcher1;
|
||||
protected InnerDispatcher _dispatcher2;
|
||||
protected ActionContextCleanUp cleanUp;
|
||||
protected FilterDispatcher filterDispatcher;
|
||||
|
||||
protected int cleanUpFilterCreateDispatcherCount = 0; // number of times clean up filter create a dispatcher
|
||||
protected int filterDispatcherCreateDispatcherCount = 0; // number of times FilterDispatcher create a dispatcher
|
||||
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
filterConfig = null;
|
||||
request = null;
|
||||
response = null;
|
||||
filterChain = null;
|
||||
filterChain2 = null;
|
||||
servletContext = null;
|
||||
_dispatcher1 = null;
|
||||
_dispatcher2 = null;
|
||||
cleanUp = null;
|
||||
filterDispatcher = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
Dispatcher.setInstance(null);
|
||||
|
||||
filterConfig = new MockFilterConfig();
|
||||
request = new MockHttpServletRequest();
|
||||
response = new MockHttpServletResponse();
|
||||
servletContext = new MockServletContext();
|
||||
|
||||
_dispatcher1 = new InnerDispatcher(servletContext){
|
||||
@Override
|
||||
public String toString() {
|
||||
return "dispatcher1";
|
||||
}
|
||||
};
|
||||
_dispatcher2 = new InnerDispatcher(servletContext){
|
||||
@Override
|
||||
public String toString() {
|
||||
return "dispatcher2";
|
||||
}
|
||||
};
|
||||
filterChain = new MockFilterChain() {
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
|
||||
filterDispatcher.doFilter(req, res, filterChain2);
|
||||
}
|
||||
};
|
||||
filterChain2 = new MockFilterChain() {
|
||||
@Override
|
||||
public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
cleanUp = new ActionContextCleanUp();
|
||||
|
||||
filterDispatcher = new FilterDispatcher() {
|
||||
@Override
|
||||
protected Dispatcher createDispatcher(FilterConfig filterConfig) {
|
||||
filterDispatcherCreateDispatcherCount++;
|
||||
return _dispatcher2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "filterDispatcher";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void testUsingFilterDispatcherOnly() throws Exception {
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 0);
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 0);
|
||||
assertFalse(_dispatcher1.init);
|
||||
assertFalse(_dispatcher1.prepare);
|
||||
assertFalse(_dispatcher1.wrapRequest);
|
||||
assertFalse(_dispatcher1.service);
|
||||
assertFalse(_dispatcher2.init);
|
||||
assertFalse(_dispatcher2.prepare);
|
||||
assertFalse(_dispatcher2.wrapRequest);
|
||||
assertFalse(_dispatcher2.service);
|
||||
|
||||
filterDispatcher.init(filterConfig);
|
||||
filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
|
||||
filterDispatcher.doFilter(request, response, filterChain2);
|
||||
filterDispatcher.destroy();
|
||||
|
||||
// we are using FilterDispatcher only, so cleanUp filter's Dispatcher should not be created.
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 0);
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 1);
|
||||
assertFalse(_dispatcher1.init);
|
||||
assertFalse(_dispatcher1.prepare);
|
||||
assertFalse(_dispatcher1.wrapRequest);
|
||||
assertFalse(_dispatcher1.service);
|
||||
assertTrue(_dispatcher2.init);
|
||||
assertTrue(_dispatcher2.prepare);
|
||||
assertTrue(_dispatcher2.wrapRequest);
|
||||
assertTrue(_dispatcher2.service);
|
||||
assertTrue(Dispatcher.getInstance() == null);
|
||||
}
|
||||
|
||||
|
||||
public void testUsingFilterDispatcherOnly_Multiple() throws Exception {
|
||||
|
||||
filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
|
||||
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 0);
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 0);
|
||||
assertFalse(_dispatcher1.prepare);
|
||||
assertFalse(_dispatcher1.wrapRequest);
|
||||
assertFalse(_dispatcher1.service);
|
||||
assertFalse(_dispatcher1.cleanUp);
|
||||
assertFalse(_dispatcher2.prepare);
|
||||
assertFalse(_dispatcher2.wrapRequest);
|
||||
assertFalse(_dispatcher2.service);
|
||||
assertFalse(_dispatcher2.cleanUp);
|
||||
|
||||
filterDispatcher.init(filterConfig);
|
||||
filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
|
||||
filterDispatcher.doFilter(request, response, filterChain2);
|
||||
filterDispatcher.doFilter(request, response, filterChain2);
|
||||
filterDispatcher.destroy();
|
||||
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 0);
|
||||
// We should create dispatcher once, although filter.doFilter(...) is called many times.
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 1);
|
||||
assertFalse(_dispatcher1.prepare);
|
||||
assertFalse(_dispatcher1.wrapRequest);
|
||||
assertFalse(_dispatcher1.service);
|
||||
assertFalse(_dispatcher1.cleanUp);
|
||||
assertTrue(_dispatcher2.prepare);
|
||||
assertTrue(_dispatcher2.wrapRequest);
|
||||
assertTrue(_dispatcher2.service);
|
||||
assertTrue(_dispatcher2.cleanUp);
|
||||
assertTrue(Dispatcher.getInstance() == null);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*public void testUsingCleanUpAndFilterDispatcher() throws Exception {
|
||||
ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
|
||||
try {
|
||||
ObjectFactory.setObjectFactory(new InnerObjectFactory());
|
||||
filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
|
||||
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 0);
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 0);
|
||||
assertFalse(_dispatcher1.prepare);
|
||||
assertFalse(_dispatcher1.wrapRequest);
|
||||
assertFalse(_dispatcher1.service);
|
||||
assertFalse(_dispatcher2.prepare);
|
||||
assertFalse(_dispatcher2.wrapRequest);
|
||||
assertFalse(_dispatcher2.service);
|
||||
|
||||
cleanUp.init(filterConfig);
|
||||
filterDispatcher.init(filterConfig);
|
||||
cleanUp.doFilter(request, response, filterChain);
|
||||
filterDispatcher.destroy();
|
||||
cleanUp.destroy();
|
||||
|
||||
assertEquals(1, cleanUpFilterCreateDispatcherCount);
|
||||
assertEquals(1, filterDispatcherCreateDispatcherCount);
|
||||
assertTrue(_dispatcher1.prepare);
|
||||
assertTrue(_dispatcher1.wrapRequest);
|
||||
assertTrue(_dispatcher1.service);
|
||||
assertFalse(_dispatcher2.prepare);
|
||||
assertFalse(_dispatcher2.wrapRequest);
|
||||
assertFalse(_dispatcher2.service);
|
||||
assertTrue(Dispatcher.getInstance() == null);
|
||||
}
|
||||
finally {
|
||||
ObjectFactory.setObjectFactory(oldObjecFactory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testUsingCleanUpAndFilterDispatcher_Multiple() throws Exception {
|
||||
ObjectFactory oldObjecFactory = ObjectFactory.getObjectFactory();
|
||||
try {
|
||||
ObjectFactory.setObjectFactory(new InnerObjectFactory());
|
||||
filterDispatcher.setActionMapper(new FilterTest.InnerMapper());
|
||||
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 0);
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 0);
|
||||
assertFalse(_dispatcher1.prepare);
|
||||
assertFalse(_dispatcher1.wrapRequest);
|
||||
assertFalse(_dispatcher1.service);
|
||||
assertFalse(_dispatcher2.prepare);
|
||||
assertFalse(_dispatcher2.wrapRequest);
|
||||
assertFalse(_dispatcher2.service);
|
||||
|
||||
cleanUp.init(filterConfig);
|
||||
filterDispatcher.init(filterConfig);
|
||||
cleanUp.doFilter(request, response, filterChain);
|
||||
cleanUp.doFilter(request, response, filterChain);
|
||||
filterDispatcher.destroy();
|
||||
cleanUp.destroy();
|
||||
|
||||
assertEquals(cleanUpFilterCreateDispatcherCount, 1);
|
||||
assertEquals(filterDispatcherCreateDispatcherCount, 1);
|
||||
assertTrue(_dispatcher1.prepare);
|
||||
assertTrue(_dispatcher1.wrapRequest);
|
||||
assertTrue(_dispatcher1.service);
|
||||
assertFalse(_dispatcher2.prepare);
|
||||
assertFalse(_dispatcher2.wrapRequest);
|
||||
assertFalse(_dispatcher2.service);
|
||||
assertTrue(Dispatcher.getInstance() == null);
|
||||
}
|
||||
finally {
|
||||
ObjectFactory.setObjectFactory(oldObjecFactory);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
class InnerDispatcher extends Dispatcher {
|
||||
public boolean init = false;
|
||||
public boolean prepare = false;
|
||||
public boolean wrapRequest = false;
|
||||
public boolean service = false;
|
||||
public boolean cleanUp = false;
|
||||
|
||||
public InnerDispatcher(ServletContext servletContext) {
|
||||
super(servletContext, new HashMap<String, String>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
init= true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Container getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare(HttpServletRequest request, HttpServletResponse response) {
|
||||
prepare = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpServletRequest wrapRequest(HttpServletRequest request) throws IOException {
|
||||
wrapRequest = true;
|
||||
return request;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serviceAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
|
||||
service = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
cleanUp = true;
|
||||
}
|
||||
}
|
||||
|
||||
class NullInnerMapper implements ActionMapper {
|
||||
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ActionMapping getMappingFromActionName(String actionName) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public String getUriFromActionMapping(ActionMapping mapping) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class InnerMapper implements ActionMapper {
|
||||
|
||||
public InnerMapper() {}
|
||||
|
||||
public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) {
|
||||
return new ActionMapping();
|
||||
}
|
||||
|
||||
public ActionMapping getMappingFromActionName(String actionName) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public String getUriFromActionMapping(ActionMapping mapping) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
class InnerObjectFactory extends ObjectFactory {
|
||||
public InnerObjectFactory() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.apache.struts2.ServletActionContext;
|
||||
import org.apache.struts2.StrutsConstants;
|
||||
import org.apache.struts2.dispatcher.FilterDispatcher;
|
||||
import org.apache.struts2.dispatcher.ng.PrepareOperations;
|
||||
import org.apache.struts2.json.annotations.SMDMethod;
|
||||
import org.apache.struts2.json.rpc.RPCError;
|
||||
import org.apache.struts2.json.rpc.RPCErrorCode;
|
||||
@@ -382,7 +382,7 @@ public class JSONInterceptor extends AbstractInterceptor {
|
||||
* @return true if debugging is turned on
|
||||
*/
|
||||
public boolean getDebug() {
|
||||
Boolean devModeOverride = FilterDispatcher.getDevModeOverride();
|
||||
Boolean devModeOverride = PrepareOperations.getDevModeOverride();
|
||||
return devModeOverride != null ? devModeOverride : this.debug;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user