zoukankan      html  css  js  c++  java
  • 2、struct2的工作流程

    1、首先执行StrutsPrepareAndExecuteFilter,调用StrutsPrepareAndExecuteFilter类的doFilter方法

    在该方法中会产生一个ActionMapping 对象,如果客户端访问不是action对象,例如访问jsp对象ActionMapping 就为空

    如果访问是action对象,则ActionMapping 不为null执行

    2、execute.executeAction(request, response, mapping);该方法调用下面的dispatcher.serviceAction(request, response, servletContext, mapping);

    3、在dispatcher.serviceAction(request, response, servletContext, mapping);调用下面的函数

    ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
    namespace, name, method, extraContext, true, false);

    创建一个ActionProxy 代理对象

    public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext) {

    ActionInvocation inv = new DefaultActionInvocation(extraContext, true);
    container.inject(inv);
    return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
    }

    在创建代理对象的同时创建了ActionInvocation 对象

    4、




    /*
     * $Id: DefaultActionSupport.java 651946 2008-04-27 13:41:38Z apetrelli $
     *
     * 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.ng.filter;
    
    import org.apache.struts2.StrutsStatics;
    import org.apache.struts2.dispatcher.Dispatcher;
    import org.apache.struts2.dispatcher.mapper.ActionMapping;
    import org.apache.struts2.dispatcher.ng.ExecuteOperations;
    import org.apache.struts2.dispatcher.ng.InitOperations;
    import org.apache.struts2.dispatcher.ng.PrepareOperations;
    
    import javax.servlet.*;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.List;
    import java.util.regex.Pattern;
    
    /**
     * Handles both the preparation and execution phases of the Struts dispatching process.  This filter is better to use
     * when you don't have another filter that needs access to action context information, such as Sitemesh.
     */
    public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter {
        protected PrepareOperations prepare;
        protected ExecuteOperations execute;
        protected List<Pattern> excludedPatterns = null;
    
        public void init(FilterConfig filterConfig) throws ServletException {
            InitOperations init = new InitOperations();
            try {
                FilterHostConfig config = new FilterHostConfig(filterConfig);
                init.initLogging(config);
                Dispatcher dispatcher = init.initDispatcher(config);
                init.initStaticContentLoader(config, dispatcher);
    
                prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
                execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
                this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
    
                postInit(dispatcher, filterConfig);
            } finally {
                init.cleanup();
            }
    
        }
    
        /**
         * Callback for post initialization
         */
        protected void postInit(Dispatcher dispatcher, FilterConfig filterConfig) {
        }
    
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
    
            try {
                prepare.setEncodingAndLocale(request, response);
                prepare.createActionContext(request, response);
                prepare.assignDispatcherToThread();
                if ( excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
                    chain.doFilter(request, response);
                } else {
                    request = prepare.wrapRequest(request);
                    ActionMapping mapping = prepare.findActionMapping(request, response, true);
                    if (mapping == null) {
                        boolean handled = execute.executeStaticResourceRequest(request, response);
                        if (!handled) {
                            chain.doFilter(request, response);
                        }
                    } else {
                        execute.executeAction(request, response, mapping);
                    }
                }
            } finally {
                prepare.cleanupRequest(request);
            }
        }
    
        public void destroy() {
            prepare.cleanupDispatcher();
        }
    }
    /*
     * $Id: DefaultActionSupport.java 651946 2008-04-27 13:41:38Z apetrelli $
     *
     * 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.ng;
    
    import org.apache.struts2.dispatcher.Dispatcher;
    import org.apache.struts2.dispatcher.StaticContentLoader;
    import org.apache.struts2.dispatcher.mapper.ActionMapping;
    import org.apache.struts2.RequestUtils;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Contains execution operations for filters
     */
    public class ExecuteOperations {
        private ServletContext servletContext;
        private Dispatcher dispatcher;
    
        public ExecuteOperations(ServletContext servletContext, Dispatcher dispatcher) {
            this.dispatcher = dispatcher;
            this.servletContext = servletContext;
        }
    
        /**
         * Tries to execute a request for a static resource
         * @return True if it was handled, false if the filter should fall through
         * @throws IOException
         * @throws ServletException
         */
        public boolean executeStaticResourceRequest(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
            // 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();
            }
    
            StaticContentLoader staticResourceLoader = dispatcher.getContainer().getInstance(StaticContentLoader.class);
            if (staticResourceLoader.canHandle(resourcePath)) {
                staticResourceLoader.findStaticResource(resourcePath, request, response);
                // The framework did its job here
                return true;
    
            } else {
                // this is a normal request, let it pass through
                return false;
            }
        }
    
        /**
         * Executes an action
         * @throws ServletException
         */
        public void executeAction(HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws ServletException {
            dispatcher.serviceAction(request, response, servletContext, mapping);
        }
    }

    /*
     * $Id: Dispatcher.java 783012 2009-06-09 14:15:54Z wesw $
     *
     * 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.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Locale;
    import java.util.Map;
    import java.util.Set;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.struts2.ServletActionContext;
    import org.apache.struts2.StrutsConstants;
    import org.apache.struts2.StrutsStatics;
    import org.apache.struts2.StrutsException;
    import org.apache.struts2.config.BeanSelectionProvider;
    import org.apache.struts2.config.DefaultPropertiesProvider;
    import org.apache.struts2.config.LegacyPropertiesConfigurationProvider;
    import org.apache.struts2.config.StrutsXmlConfigurationProvider;
    import org.apache.struts2.dispatcher.mapper.ActionMapping;
    import org.apache.struts2.dispatcher.multipart.MultiPartRequest;
    import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper;
    import org.apache.struts2.util.AttributeMap;
    import org.apache.struts2.util.ClassLoaderUtils;
    import org.apache.struts2.util.ObjectFactoryDestroyable;
    import org.apache.struts2.views.freemarker.FreemarkerManager;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionProxy;
    import com.opensymphony.xwork2.ActionProxyFactory;
    import com.opensymphony.xwork2.ObjectFactory;
    import com.opensymphony.xwork2.Result;
    import com.opensymphony.xwork2.config.Configuration;
    import com.opensymphony.xwork2.config.ConfigurationException;
    import com.opensymphony.xwork2.config.ConfigurationManager;
    import com.opensymphony.xwork2.config.ConfigurationProvider;
    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.config.providers.XmlConfigurationProvider;
    import com.opensymphony.xwork2.inject.Container;
    import com.opensymphony.xwork2.inject.ContainerBuilder;
    import com.opensymphony.xwork2.inject.Inject;
    import com.opensymphony.xwork2.interceptor.Interceptor;
    import com.opensymphony.xwork2.util.FileManager;
    import com.opensymphony.xwork2.util.LocalizedTextUtil;
    import com.opensymphony.xwork2.util.ValueStack;
    import com.opensymphony.xwork2.util.ValueStackFactory;
    import com.opensymphony.xwork2.util.location.LocatableProperties;
    import com.opensymphony.xwork2.util.location.Location;
    import com.opensymphony.xwork2.util.location.LocationUtils;
    import com.opensymphony.xwork2.util.logging.Logger;
    import com.opensymphony.xwork2.util.logging.LoggerFactory;
    import com.opensymphony.xwork2.util.profiling.UtilTimerStack;
    
    import freemarker.template.Template;
    
    /**
     * A utility class the actual dispatcher delegates most of its tasks to. Each instance
     * of the primary dispatcher holds an instance of this dispatcher to be shared for
     * all requests.
     *
     * @see org.apache.struts2.dispatcher.FilterDispatcher
     */
    public class Dispatcher {
    
        /**
         * Provide a logging instance.
         */
        private static final Logger LOG = LoggerFactory.getLogger(Dispatcher.class);
    
        /**
         * Provide a thread local instance.
         */
        private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();
    
        /**
         * Store list of DispatcherListeners.
         */
        private static List<DispatcherListener> dispatcherListeners =
            new CopyOnWriteArrayList<DispatcherListener>();
    
        /**
         * Store ConfigurationManager instance, set on init.
         */
        private ConfigurationManager configurationManager;
    
        /**
         * Store state of  StrutsConstants.STRUTS_DEVMODE setting.
         */
        private boolean devMode;
    
        /**
         * Store state of StrutsConstants.STRUTS_I18N_ENCODING setting.
         */
        private String defaultEncoding;
    
        /**
         * Store state of StrutsConstants.STRUTS_LOCALE setting.
         */
        private String defaultLocale;
    
        /**
         * Store state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
         */
        private String multipartSaveDir;
    
        /**
         * Stores the value of StrutsConstants.STRUTS_MULTIPART_HANDLER setting
         */
        private String multipartHandlerName;
    
        /**
         * Provide list of default configuration files.
         */
        private static final String DEFAULT_CONFIGURATION_PATHS = "struts-default.xml,struts-plugin.xml,struts.xml";
    
        /**
         * Store state of STRUTS_DISPATCHER_PARAMETERSWORKAROUND.
         * <p/>
         * The workaround is for WebLogic.
         * We try to autodect WebLogic on Dispatcher init.
         * The workaround can also be enabled manually.
         */
        private boolean paramsWorkaroundEnabled = false;
    
        /**
         * Provide the dispatcher instance for the current thread.
         *
         * @return The dispatcher instance
         */
        public static Dispatcher getInstance() {
            return instance.get();
        }
    
        /**
         * Store the dispatcher instance for this thread.
         *
         * @param instance The instance
         */
        public static void setInstance(Dispatcher instance) {
            Dispatcher.instance.set(instance);
        }
    
        /**
         * Add a dispatcher lifecycle listener.
         *
         * @param listener The listener to add
         */
        public static void addDispatcherListener(DispatcherListener listener) {
            dispatcherListeners.add(listener);
        }
    
        /**
         * Remove a specific dispatcher lifecycle listener.
         *
         * @param listener The listener
         */
        public static void removeDispatcherListener(DispatcherListener listener) {
            dispatcherListeners.remove(listener);
        }
    
        private ServletContext servletContext;
        private Map<String, String> initParams;
    
        private ValueStackFactory valueStackFactory;
    
    
        /**
         * Create the Dispatcher instance for a given ServletContext and set of initialization parameters.
         *
         * @param servletContext Our servlet context
         * @param initParams The set of initialization parameters
         */
        public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {
            this.servletContext = servletContext;
            this.initParams = initParams;
        }
    
        /**
         * Modify state of StrutsConstants.STRUTS_DEVMODE setting.
         * @param mode New setting
         */
        @Inject(StrutsConstants.STRUTS_DEVMODE)
        public void setDevMode(String mode) {
            devMode = "true".equals(mode);
        }
    
        /**
         * Modify state of StrutsConstants.STRUTS_LOCALE setting.
         * @param val New setting
         */
        @Inject(value=StrutsConstants.STRUTS_LOCALE, required=false)
        public void setDefaultLocale(String val) {
            defaultLocale = val;
        }
    
        /**
         * Modify state of StrutsConstants.STRUTS_I18N_ENCODING setting.
         * @param val New setting
         */
        @Inject(StrutsConstants.STRUTS_I18N_ENCODING)
        public void setDefaultEncoding(String val) {
            defaultEncoding = val;
        }
    
        /**
         * Modify state of StrutsConstants.STRUTS_MULTIPART_SAVEDIR setting.
         * @param val New setting
         */
        @Inject(StrutsConstants.STRUTS_MULTIPART_SAVEDIR)
        public void setMultipartSaveDir(String val) {
            multipartSaveDir = val;
        }
    
        @Inject(StrutsConstants.STRUTS_MULTIPART_HANDLER)
        public void setMultipartHandler(String val) {
            multipartHandlerName = val;
        }
    
        @Inject
        public void setValueStackFactory(ValueStackFactory valueStackFactory) {
            this.valueStackFactory = valueStackFactory;
        }
    
        /**
         * Releases all instances bound to this dispatcher instance.
         */
        public void cleanup() {
    
            // clean up ObjectFactory
            ObjectFactory objectFactory = getContainer().getInstance(ObjectFactory.class);
            if (objectFactory == null) {
                LOG.warn("Object Factory is null, something is seriously wrong, no clean up will be performed");
            }
            if (objectFactory instanceof ObjectFactoryDestroyable) {
                try {
                    ((ObjectFactoryDestroyable)objectFactory).destroy();
                }
                catch(Exception e) {
                    // catch any exception that may occured during destroy() and log it
                    LOG.error("exception occurred while destroying ObjectFactory ["+objectFactory+"]", e);
                }
            }
    
            // clean up Dispatcher itself for this thread
            instance.set(null);
    
            // clean up DispatcherListeners
            if (!dispatcherListeners.isEmpty()) {
                for (DispatcherListener l : dispatcherListeners) {
                    l.dispatcherDestroyed(this);
                }
            }
    
            // clean up all interceptors by calling their destroy() method
            Set<Interceptor> interceptors = new HashSet<Interceptor>();
            Collection<PackageConfig> packageConfigs = configurationManager.getConfiguration().getPackageConfigs().values();
            for (PackageConfig packageConfig : packageConfigs) {
                for (Object config : packageConfig.getAllInterceptorConfigs().values()) {
                    if (config instanceof InterceptorStackConfig) {
                        for (InterceptorMapping interceptorMapping : ((InterceptorStackConfig) config).getInterceptors()) {
                            interceptors.add(interceptorMapping.getInterceptor());
                        }
                    }
                }
            }
            for (Interceptor interceptor : interceptors) {
                interceptor.destroy();
            }
    
            //cleanup action context
            ActionContext.setContext(null);
    
            // clean up configuration
            configurationManager.destroyConfiguration();
            configurationManager = null;
        }
    
        private void init_DefaultProperties() {
            configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
        }
        
        private void init_LegacyStrutsProperties() {
            configurationManager.addConfigurationProvider(new LegacyPropertiesConfigurationProvider());
        }
    
        private void init_TraditionalXmlConfigurations() {
            String configPaths = initParams.get("config");
            if (configPaths == null) {
                configPaths = DEFAULT_CONFIGURATION_PATHS;
            }
            String[] files = configPaths.split("\s*[,]\s*");
            for (String file : files) {
                if (file.endsWith(".xml")) {
                    if ("xwork.xml".equals(file)) {
                        configurationManager.addConfigurationProvider(new XmlConfigurationProvider(file, false));
                    } else {
                        configurationManager.addConfigurationProvider(new StrutsXmlConfigurationProvider(file, false, servletContext));
                    }
                } else {
                    throw new IllegalArgumentException("Invalid configuration file name");
                }
            }
        }
    
        private void init_CustomConfigurationProviders() {
            String configProvs = initParams.get("configProviders");
            if (configProvs != null) {
                String[] classes = configProvs.split("\s*[,]\s*");
                for (String cname : classes) {
                    try {
                        Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
                        ConfigurationProvider prov = (ConfigurationProvider)cls.newInstance();
                        configurationManager.addConfigurationProvider(prov);
                    } catch (InstantiationException e) {
                        throw new ConfigurationException("Unable to instantiate provider: "+cname, e);
                    } catch (IllegalAccessException e) {
                        throw new ConfigurationException("Unable to access provider: "+cname, e);
                    } catch (ClassNotFoundException e) {
                        throw new ConfigurationException("Unable to locate provider class: "+cname, e);
                    }
                }
            }
        }
    
        private void init_FilterInitParameters() {
            configurationManager.addConfigurationProvider(new ConfigurationProvider() {
                public void destroy() {}
                public void init(Configuration configuration) throws ConfigurationException {}
                public void loadPackages() throws ConfigurationException {}
                public boolean needsReload() { return false; }
    
                public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException {
                    props.putAll(initParams);
                }
            });
        }
    
        private void init_AliasStandardObjects() {
            configurationManager.addConfigurationProvider(new BeanSelectionProvider());
        }
    
        private Container init_PreloadConfiguration() {
            Configuration config = configurationManager.getConfiguration();
            Container container = config.getContainer();
    
            boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class, StrutsConstants.STRUTS_I18N_RELOAD));
            LocalizedTextUtil.setReloadBundles(reloadi18n);
    
            return container;
        }
    
        private void init_CheckConfigurationReloading(Container container) {
            FileManager.setReloadingConfigs("true".equals(container.getInstance(String.class,
                    StrutsConstants.STRUTS_CONFIGURATION_XML_RELOAD)));
        }
    
        private void init_CheckWebLogicWorkaround(Container container) {
            // test whether param-access workaround needs to be enabled
            if (servletContext != null && servletContext.getServerInfo() != null
                    && servletContext.getServerInfo().indexOf("WebLogic") >= 0) {
                LOG.info("WebLogic server detected. Enabling Struts parameter access work-around.");
                paramsWorkaroundEnabled = true;
            } else {
                paramsWorkaroundEnabled = "true".equals(container.getInstance(String.class,
                        StrutsConstants.STRUTS_DISPATCHER_PARAMETERSWORKAROUND));
            }
        }
    
        /**
         * Load configurations, including both XML and zero-configuration strategies,
         * and update optional settings, including whether to reload configurations and resource files.
         */
        public void init() {
    
            if (configurationManager == null) {
                configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
            }
    
            try {
                init_DefaultProperties(); // [1]
                init_TraditionalXmlConfigurations(); // [2]
                init_LegacyStrutsProperties(); // [3]
                init_CustomConfigurationProviders(); // [5]
                init_FilterInitParameters() ; // [6]
                init_AliasStandardObjects() ; // [7]
    
                Container container = init_PreloadConfiguration();
                container.inject(this);
                init_CheckConfigurationReloading(container);
                init_CheckWebLogicWorkaround(container);
    
                if (!dispatcherListeners.isEmpty()) {
                    for (DispatcherListener l : dispatcherListeners) {
                        l.dispatcherInitialized(this);
                    }
                }
            } catch (Exception ex) {
                if (LOG.isErrorEnabled())
                    LOG.error("Dispatcher initialization failed", ex);
                throw new StrutsException(ex);
            }
        }
    
        /**
         * Load Action class for mapping and invoke the appropriate Action method, or go directly to the Result.
         * <p/>
         * This method first creates the action context from the given parameters,
         * and then loads an <tt>ActionProxy</tt> from the given action name and namespace.
         * After that, the Action method is executed and output channels through the response object.
         * Actions not found are sent back to the user via the {@link Dispatcher#sendError} method,
         * using the 404 return code.
         * All other errors are reported by throwing a ServletException.
         *
         * @param request  the HttpServletRequest object
         * @param response the HttpServletResponse object
         * @param mapping  the action mapping object
         * @throws ServletException when an unknown error occurs (not a 404, but typically something that
         *                          would end up as a 5xx by the servlet container)
         * @param context Our ServletContext object
         */
        public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context,
                                  ActionMapping mapping) throws ServletException {
    
            Map<String, Object> extraContext = createContextMap(request, response, mapping, context);
    
            // If there was a previous value stack, then create a new copy and pass it in to be used by the new Action
            ValueStack stack = (ValueStack) request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
            boolean nullStack = stack == null;
            if (nullStack) {
                ActionContext ctx = ActionContext.getContext();
                if (ctx != null) {
                    stack = ctx.getValueStack();
                }
            }
            if (stack != null) {
                extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack));
            }
    
            String timerKey = "Handling request from Dispatcher";
            try {
                UtilTimerStack.push(timerKey);
                String namespace = mapping.getNamespace();
                String name = mapping.getName();
                String method = mapping.getMethod();
    
                Configuration config = configurationManager.getConfiguration();
                ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(
                        namespace, name, method, extraContext, true, false);
    
                request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());
    
                // if the ActionMapping says to go straight to a result, do it!
                if (mapping.getResult() != null) {
                    Result result = mapping.getResult();
                    result.execute(proxy.getInvocation());
                } else {
                    proxy.execute();
                }
    
                // If there was a previous value stack then set it back onto the request
                if (!nullStack) {
                    request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack);
                }
            } catch (ConfigurationException e) {
                // WW-2874 Only log error if in devMode
                if(devMode) {
                    LOG.error("Could not find action or result", e);
                }
                else {
                    LOG.warn("Could not find action or result", e);
                }
                sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);
            } catch (Exception e) {
                sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e);
            } finally {
                UtilTimerStack.pop(timerKey);
            }
        }
    
        /**
         * Create a context map containing all the wrapped request objects
         *
         * @param request The servlet request
         * @param response The servlet response
         * @param mapping The action mapping
         * @param context The servlet context
         * @return A map of context objects
         */
        public Map<String,Object> createContextMap(HttpServletRequest request, HttpServletResponse response,
                ActionMapping mapping, ServletContext context) {
    
            // request map wrapping the http request objects
            Map requestMap = new RequestMap(request);
    
            // parameters map wrapping the http parameters.  ActionMapping parameters are now handled and applied separately
            Map params = new HashMap(request.getParameterMap());
    
            // session map wrapping the http session
            Map session = new SessionMap(request);
    
            // application map wrapping the ServletContext
            Map application = new ApplicationMap(context);
    
            Map<String,Object> extraContext = createContextMap(requestMap, params, session, application, request, response, context);
    
            if (mapping != null) {
                extraContext.put(ServletActionContext.ACTION_MAPPING, mapping);
            }
            return extraContext;
        }
    
        /**
         * Merge all application and servlet attributes into a single <tt>HashMap</tt> to represent the entire
         * <tt>Action</tt> context.
         *
         * @param requestMap     a Map of all request attributes.
         * @param parameterMap   a Map of all request parameters.
         * @param sessionMap     a Map of all session attributes.
         * @param applicationMap a Map of all servlet context attributes.
         * @param request        the HttpServletRequest object.
         * @param response       the HttpServletResponse object.
         * @param servletContext the ServletContextmapping object.
         * @return a HashMap representing the <tt>Action</tt> context.
         */
        public HashMap<String,Object> createContextMap(Map requestMap,
                                        Map parameterMap,
                                        Map sessionMap,
                                        Map applicationMap,
                                        HttpServletRequest request,
                                        HttpServletResponse response,
                                        ServletContext servletContext) {
            HashMap<String,Object> extraContext = new HashMap<String,Object>();
            extraContext.put(ActionContext.PARAMETERS, new HashMap(parameterMap));
            extraContext.put(ActionContext.SESSION, sessionMap);
            extraContext.put(ActionContext.APPLICATION, applicationMap);
    
            Locale locale;
            if (defaultLocale != null) {
                locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
            } else {
                locale = request.getLocale();
            }
    
            extraContext.put(ActionContext.LOCALE, locale);
            //extraContext.put(ActionContext.DEV_MODE, Boolean.valueOf(devMode));
    
            extraContext.put(StrutsStatics.HTTP_REQUEST, request);
            extraContext.put(StrutsStatics.HTTP_RESPONSE, response);
            extraContext.put(StrutsStatics.SERVLET_CONTEXT, servletContext);
    
            // helpers to get access to request/session/application scope
            extraContext.put("request", requestMap);
            extraContext.put("session", sessionMap);
            extraContext.put("application", applicationMap);
            extraContext.put("parameters", parameterMap);
    
            AttributeMap attrMap = new AttributeMap(extraContext);
            extraContext.put("attr", attrMap);
    
            return extraContext;
        }
    
        /**
         * Return the path to save uploaded files to (this is configurable).
         *
         * @return the path to save uploaded files to
         * @param servletContext Our ServletContext
         */
        private String getSaveDir(ServletContext servletContext) {
            String saveDir = multipartSaveDir.trim();
    
            if (saveDir.equals("")) {
                File tempdir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
                LOG.info("Unable to find 'struts.multipart.saveDir' property setting. Defaulting to javax.servlet.context.tempdir");
    
                if (tempdir != null) {
                    saveDir = tempdir.toString();
                    setMultipartSaveDir(saveDir);
                }
            } else {
                File multipartSaveDir = new File(saveDir);
    
                if (!multipartSaveDir.exists()) {
                    if (multipartSaveDir.mkdir() == false) {
                        String logMessage;
                    try {
                            logMessage = "Could not find create multipart save directory '"+multipartSaveDir.getCanonicalPath()+"'.";
                    } catch (IOException e) {
                            logMessage = "Could not find create multipart save directory '"+multipartSaveDir.toString()+"'.";
                    }
                    if(devMode) {
                            LOG.error(logMessage);
                    }
                    else {
                            LOG.warn(logMessage);
                    }
                    }
                }
            }
    
            if (LOG.isDebugEnabled()) {
                LOG.debug("saveDir=" + saveDir);
            }
    
            return saveDir;
        }
    
        /**
         * Prepare a request, including setting the encoding and locale.
         *
         * @param request The request
         * @param response The response
         */
        public void prepare(HttpServletRequest request, HttpServletResponse response) {
            String encoding = null;
            if (defaultEncoding != null) {
                encoding = defaultEncoding;
            }
    
            Locale locale = null;
            if (defaultLocale != null) {
                locale = LocalizedTextUtil.localeFromString(defaultLocale, request.getLocale());
            }
    
            if (encoding != null) {
                try {
                    request.setCharacterEncoding(encoding);
                } catch (Exception e) {
                    LOG.error("Error setting character encoding to '" + encoding + "' - ignoring.", e);
                }
            }
    
            if (locale != null) {
                response.setLocale(locale);
            }
    
            if (paramsWorkaroundEnabled) {
                request.getParameter("foo"); // simply read any parameter (existing or not) to "prime" the request
            }
        }
    
        /**
         * Wrap and return the given request or return the original request object.
         * </p>
         * This method transparently handles multipart data as a wrapped class around the given request.
         * Override this method to handle multipart requests in a special way or to handle other types of requests.
         * Note, {@link org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper} is
         * flexible - look first to that object before overriding this method to handle multipart data.
         *
         * @param request the HttpServletRequest object.
         * @param servletContext Our ServletContext object
         * @return a wrapped request or original request.
         * @see org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper
         * @throws java.io.IOException on any error.
         */
        public HttpServletRequest wrapRequest(HttpServletRequest request, ServletContext servletContext) throws IOException {
            // don't wrap more than once
            if (request instanceof StrutsRequestWrapper) {
                return request;
            }
    
            String content_type = request.getContentType();
            if (content_type != null && content_type.indexOf("multipart/form-data") != -1) {
                MultiPartRequest mpr = null;
                //check for alternate implementations of MultiPartRequest
                Set<String> multiNames = getContainer().getInstanceNames(MultiPartRequest.class);
                if (multiNames != null) {
                    for (String multiName : multiNames) {
                        if (multiName.equals(multipartHandlerName)) {
                            mpr = getContainer().getInstance(MultiPartRequest.class, multiName);
                        }
                    }
                }
                if (mpr == null ) {
                    mpr = getContainer().getInstance(MultiPartRequest.class);
                }
                request = new MultiPartRequestWrapper(mpr, request, getSaveDir(servletContext));
            } else {
                request = new StrutsRequestWrapper(request);
            }
    
            return request;
        }
    
        /**
         * Send an HTTP error response code.
         *
         * @param request  the HttpServletRequest object.
         * @param response the HttpServletResponse object.
         * @param code     the HttpServletResponse error code (see {@link javax.servlet.http.HttpServletResponse} for possible error codes).
         * @param e        the Exception that is reported.
         * @param ctx      the ServletContext object.
         */
        public void sendError(HttpServletRequest request, HttpServletResponse response,
                ServletContext ctx, int code, Exception e) {
            if (devMode) {
                response.setContentType("text/html");
    
                try {
                    FreemarkerManager mgr = getContainer().getInstance(FreemarkerManager.class);
    
                    freemarker.template.Configuration config = mgr.getConfiguration(ctx);
                    Template template = config.getTemplate("/org/apache/struts2/dispatcher/error.ftl");
    
                    List<Throwable> chain = new ArrayList<Throwable>();
                    Throwable cur = e;
                    chain.add(cur);
                    while ((cur = cur.getCause()) != null) {
                        chain.add(cur);
                    }
    
                    HashMap<String,Object> data = new HashMap<String,Object>();
                    data.put("exception", e);
                    data.put("unknown", Location.UNKNOWN);
                    data.put("chain", chain);
                    data.put("locator", new Locator());
                    template.process(data, response.getWriter());
                    response.getWriter().close();
                } catch (Exception exp) {
                    try {
                        response.sendError(code, "Unable to show problem report: " + exp);
                    } catch (IOException ex) {
                        // we're already sending an error, not much else we can do if more stuff breaks
                    }
                }
            } else {
                try {
                    // WW-1977: Only put errors in the request when code is a 500 error
                    if (code == HttpServletResponse.SC_INTERNAL_SERVER_ERROR) {
                        // send a http error response to use the servlet defined error handler
                        // make the exception availible to the web.xml defined error page
                        request.setAttribute("javax.servlet.error.exception", e);
    
                        // for compatibility
                        request.setAttribute("javax.servlet.jsp.jspException", e);
                    }
    
                    // send the error response
                    response.sendError(code, e.getMessage());
                } catch (IOException e1) {
                    // we're already sending an error, not much else we can do if more stuff breaks
                }
            }
        }
    
        
    
        /**
         * Provide an accessor class for static XWork utility.
         */
        public static class Locator {
            public Location getLocation(Object obj) {
                Location loc = LocationUtils.getLocation(obj);
                if (loc == null) {
                    return Location.UNKNOWN;
                }
                return loc;
            }
        }
    
        /**
         * Expose the ConfigurationManager instance.
         *
         * @return The instance
         */
        public ConfigurationManager getConfigurationManager() {
            return configurationManager;
        }
    
        /**
         * Modify the ConfigurationManager instance
         *
         * @param mgr The configuration manager
         */
        public void setConfigurationManager(ConfigurationManager mgr) {
            this.configurationManager = mgr;
        }
    
        /**
         * Expose the dependency injection container.
         * @return Our dependency injection container
         */
        public Container getContainer() {
            ConfigurationManager mgr = getConfigurationManager();
            if (mgr == null) {
                throw new IllegalStateException("The configuration manager shouldn't be null");
            } else {
                Configuration config = mgr.getConfiguration();
                if (config == null) {
                    throw new IllegalStateException("Unable to load configuration");
                } else {
                    return config.getContainer();
                }
            }
        }
    }
    
    
    
     
    /*
     * Copyright (c) 2002-2007 by OpenSymphony
     * All rights reserved.
     */
    package com.opensymphony.xwork2;
    
    import com.opensymphony.xwork2.inject.Container;
    import com.opensymphony.xwork2.inject.Inject;
    
    import java.util.Map;
    
    
    /**
     * Default factory for {@link com.opensymphony.xwork2.ActionProxyFactory}.
     *
     * @author Jason Carreira
     */
    public class DefaultActionProxyFactory implements ActionProxyFactory {
    
        protected Container container;
        
        public DefaultActionProxyFactory() {
            super();
        }
        
        @Inject
        public void setContainer(Container container) {
            this.container = container;
        }
        
        public ActionProxy createActionProxy(String namespace, String actionName, Map<String, Object> extraContext) {
            return createActionProxy(namespace, actionName, null, extraContext, true, true);
        }
    
        public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext) {
            return createActionProxy(namespace, actionName, methodName, extraContext, true, true);
        }
    
        public ActionProxy createActionProxy(String namespace, String actionName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext) {
            return createActionProxy(namespace, actionName, null, extraContext, executeResult, cleanupContext);
        }
    
        public ActionProxy createActionProxy(String namespace, String actionName, String methodName, Map<String, Object> extraContext, boolean executeResult, boolean cleanupContext) {
            
            ActionInvocation inv = new DefaultActionInvocation(extraContext, true);
            container.inject(inv);
            return createActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
        }
        
        public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, boolean executeResult, boolean cleanupContext) {
            
            return createActionProxy(inv, namespace, actionName, null, executeResult, cleanupContext);
        }
    
        public ActionProxy createActionProxy(ActionInvocation inv, String namespace, String actionName, String methodName, boolean executeResult, boolean cleanupContext) {
    
            DefaultActionProxy proxy = new DefaultActionProxy(inv, namespace, actionName, methodName, executeResult, cleanupContext);
            container.inject(proxy);
            proxy.prepare();
            return proxy;
        }
    
    }
    
    
    
    
    
  • 相关阅读:
    LeetCode 38. 外观数列
    LeetCode 33. 搜索旋转排序数组
    LeetCode 31. 下一个排列
    LeetCode 34. 在排序数组中查找元素的第一个和最后一个位置
    LeetCode 29. 两数相除
    LeetCode 22. 括号生成
    LeetCode 1. 两数之和
    LeetCode 17. 电话号码的字母组合
    LeetCode 18. 四数之和
    LeetCode 16. 最接近的三数之和
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7999835.html
Copyright © 2011-2022 走看看