`
zysoo
  • 浏览: 28057 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Struts 1 源码研究- Action

阅读更多
struts的action类。
基本上是对一些message,error,token的操作。
struts中,action方法需要对action类进行继承。
通过调用execute方法,http请求都交与RequestProcessor处理。
package org.apache.struts.action;

import org.apache.struts.Globals;
import org.apache.struts.config.ModuleConfig;
import org.apache.struts.util.MessageResources;
import org.apache.struts.util.ModuleUtils;
import org.apache.struts.util.RequestUtils;
import org.apache.struts.util.TokenProcessor;

import javax.servlet.ServletContext;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import java.util.Locale;

/**
* Action 是介于http请求和业务逻辑之间的控制器。
* 对于每一个http请求,控制器会选择相应的action,调用execute方法处理
* Action必须在线程安全的方式下处理,因为控制器对于多个同步的请求共享实例。
* 实例和静态变量不能储存和请求相关的信息。但是可以共享跨实例的资源
  * <li>Access to other resources (JavaBeans, session variables, etc.) MUST be
* synchronized if those resources require protection. (Generally, however,
* resource classes should be designed to provide their own protection where
* necessary.</li>
* 访问其他资源(比如javabeans,session 变量等)必须要同步
* </ul>
*
* <p>When an <code>Action</code> instance is first created, the controller
* will call <code>setServlet</code> with a non-null argument to identify the
* servlet instance to which this Action is attached. When the servlet is to
* be shut down (or restarted), the <code>setServlet</code> method will be
* called with a <code>null</code> argument, which can be used to clean up any
* allocated resources in use by this Action.</p>
* 当Action实例刚被创建,控制器会调用setServlet方法来标识Servlet实例。
* 当serevlet被关闭时候,控制调用有参数的setServlet方法来释放资源。
*
* @version $Rev: 471754 $ $Date: 2005-08-26 21:58:39 -0400 (Fri, 26 Aug 2005)
*          $
*/
public class Action {
    /**
     * token实例,防止事务的重复提交
     */
    private static TokenProcessor token = TokenProcessor.getInstance();

    // NOTE: We can make the tken  variable protected and remove Action's
    // token methods or leave it private and allow the token methods to
    // delegate their calls.
    // ----------------------------------------------------- Instance Variables

    /**
     * <p>The servlet to which we are attached.</p>
     */
    protected transient ActionServlet servlet = null;

    // ------------------------------------------------------------- Properties

    /**
     * <p>Return the servlet instance to which we are attached.</p>
     *
     * @return The servlet instance to which we are attached.
     */
    public ActionServlet getServlet() {
        return (this.servlet);
    }

    /**
     * <p>Set the servlet instance to which we are attached (if
     * <code>servlet</code> is non-null), or release any allocated resources
     * (if <code>servlet</code> is null).</p>
     *
     * @param servlet The new controller servlet, if any
     */
    public void setServlet(ActionServlet servlet) {
        this.servlet = servlet;

        // :FIXME: Is this suppose to release resources?
    }

    // --------------------------------------------------------- Public Methods

    /**    
     * 非http的请求的处理方法    
     */
    public ActionForward execute(ActionMapping mapping, ActionForm form,
        ServletRequest request, ServletResponse response)
        throws Exception {
        try {
            return execute(mapping, form, (HttpServletRequest) request,
                (HttpServletResponse) response);
        } catch (ClassCastException e) {
            return null;
        }
    }

    /**
     * 处理http的请求    
     */
    public ActionForward execute(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        return null;
    }

    // ---------------------------------------------------- Protected Methods

    /**
     *在request中设置message值,供页面<html:message 标签中使用
     */
    protected void addMessages(HttpServletRequest request,
        ActionMessages messages) {
        if (messages == null) {
            //  bad programmer! *slap*
            return;
        }

        // get any existing messages from the request, or make a new one
        ActionMessages requestMessages =
            (ActionMessages) request.getAttribute(Globals.MESSAGE_KEY);

        if (requestMessages == null) {
            requestMessages = new ActionMessages();
        }

        // add incoming messages
        requestMessages.add(messages);

        // if still empty, just wipe it out from the request
        if (requestMessages.isEmpty()) {
            request.removeAttribute(Globals.MESSAGE_KEY);

            return;
        }

        // Save the messages
        request.setAttribute(Globals.MESSAGE_KEY, requestMessages);
    }

    /**
     * 向Request中添加errors,页面中使用<html:errors
     *
     * @param request The servlet request we are processing
     * @param errors  Errors object
     * @since Struts 1.2.1
     */
    protected void addErrors(HttpServletRequest request, ActionMessages errors) {
        if (errors == null) {
            //  bad programmer! *slap*
            return;
        }

        // get any existing errors from the request, or make a new one
        ActionMessages requestErrors =
            (ActionMessages) request.getAttribute(Globals.ERROR_KEY);

        if (requestErrors == null) {
            requestErrors = new ActionMessages();
        }

        // add incoming errors
        requestErrors.add(errors);

        // if still empty, just wipe it out from the request
        if (requestErrors.isEmpty()) {
            request.removeAttribute(Globals.ERROR_KEY);

            return;
        }

        // Save the errors
        request.setAttribute(Globals.ERROR_KEY, requestErrors);
    }

    /**
     *生成token,防止重复提交事务
    
     */
    protected String generateToken(HttpServletRequest request) {
        return token.generateToken(request);
    }

    /**
     *重新得到前一个action生成的任何错误。
     *可以防止saveErrors()抹去任何已经存在的错误
    
     */
    protected ActionMessages getErrors(HttpServletRequest request) {
        ActionMessages errors =
            (ActionMessages) request.getAttribute(Globals.ERROR_KEY);

        if (errors == null) {
            errors = new ActionMessages();
        }

        return errors;
    }

    /**
     * <p>Return the user's currently selected Locale.</p>
     *
     * @param request The request we are processing
     * @return The user's currently selected Locale.
     */
    protected Locale getLocale(HttpServletRequest request) {
        return RequestUtils.getUserLocale(request, null);
    }

    /**
     * <p> Retrieves any existing messages placed in the request by previous
     * actions. This method could be called instead of creating a <code>new
     * ActionMessages()</code> at the beginning of an <code>Action</code> This
     * will prevent saveMessages() from wiping out any existing Messages </p>
     *
     * @param request The servlet request we are processing
     * @return the Messages that already exist in the request, or a new
     *         ActionMessages object if empty.
     * @since Struts 1.2.1
     */
    protected ActionMessages getMessages(HttpServletRequest request) {
        ActionMessages messages =
            (ActionMessages) request.getAttribute(Globals.MESSAGE_KEY);

        if (messages == null) {
            messages = new ActionMessages();
        }

        return messages;
    }

    /**
     * <p>Return the default message resources for the current module.</p>
     *
     * @param request The servlet request we are processing
     * @return The default message resources for the current module.
     * @since Struts 1.1
     */
    protected MessageResources getResources(HttpServletRequest request) {
        return ((MessageResources) request.getAttribute(Globals.MESSAGES_KEY));
    }

    /**
     * <p>Return the specified message resources for the current module.</p>
     *
     * @param request The servlet request we are processing
     * @param key     The key specified in the message-resources element for
     *                the requested bundle.
     * @return The specified message resource for the current module.
     * @since Struts 1.1
     */
    protected MessageResources getResources(HttpServletRequest request,
        String key) {
        // Identify the current module
        ServletContext context = getServlet().getServletContext();
        ModuleConfig moduleConfig =
            ModuleUtils.getInstance().getModuleConfig(request, context);

        // Return the requested message resources instance
        return (MessageResources) context.getAttribute(key
            + moduleConfig.getPrefix());
    }

    /**
     * <p>Returns <code>true</code> if the current form's cancel button was
     * pressed. This method will check if the <code>Globals.CANCEL_KEY</code>
     * request attribute has been set, which normally occurs if the cancel
     * button generated by <strong>CancelTag</strong> was pressed by the user
     * in the current request. If <code>true</code>, validation performed by
     * an <strong>ActionForm</strong>'s <code>validate()</code> method will
     * have been skipped by the controller servlet.</p>
     *
     * <p> Since Action 1.3.0, the mapping for a cancellable Action must also have
     * the new "cancellable" property set to true. If "cancellable" is not set, and
     * the magic Cancel token is found in the request, the standard Composable
     * Request Processor will throw an InvalidCancelException. </p>
     *
     * @param request The servlet request we are processing
     * @return <code>true</code> if the cancel button was pressed;
     *         <code>false</code> otherwise.
     */
    protected boolean isCancelled(HttpServletRequest request) {
        return (request.getAttribute(Globals.CANCEL_KEY) != null);
    }

    /**
     * <p>Return <code>true</code> if there is a transaction token stored in
     * the user's current session, and the value submitted as a request
     * parameter with this action matches it. Returns <code>false</code> under
     * any of the following circumstances:</p>
     *
     * <ul>
     *
     * <li>No session associated with this request</li>
     *
     * <li>No transaction token saved in the session</li>
     *
     * <li>No transaction token included as a request parameter</li>
     *
     * <li>The included transaction token value does not match the transaction
     * token in the user's session</li>
     *
     * </ul>
     *
     * @param request The servlet request we are processing
     * @return <code>true</code> if there is a transaction token and it is
     *         valid; <code>false</code> otherwise.
     */
    protected boolean isTokenValid(HttpServletRequest request) {
        return token.isTokenValid(request, false);
    }

    /**
     * <p>Return <code>true</code> if there is a transaction token stored in
     * the user's current session, and the value submitted as a request
     * parameter with this action matches it. Returns <code>false</code> under
     * any of the following circumstances:</p>
     *
     * <ul>
     *
     * <li>No session associated with this request</li> <li>No transaction
     * token saved in the session</li>
     *
     * <li>No transaction token included as a request parameter</li>
     *
     * <li>The included transaction token value does not match the transaction
     * token in the user's session</li>
     *
     * </ul>
     *
     * @param request The servlet request we are processing
     * @param reset   Should we reset the token after checking it?
     * @return <code>true</code> if there is a transaction token and it is
     *         valid; <code>false</code> otherwise.
     */
    protected boolean isTokenValid(HttpServletRequest request, boolean reset) {
        return token.isTokenValid(request, reset);
    }

    /**
     * <p>Reset the saved transaction token in the user's session. This
     * indicates that transactional token checking will not be needed on the
     * next request that is submitted.</p>
     *
     * @param request The servlet request we are processing
     */
    protected void resetToken(HttpServletRequest request) {
        token.resetToken(request);
    }

    /**
     * <p>Save the specified error messages keys into the appropriate request
     * attribute for use by the &lt;html:errors&gt; tag, if any messages are
     * required. Otherwise, ensure that the request attribute is not
     * created.</p>
     *
     * @param request The servlet request we are processing
     * @param errors  Error messages object
     * @since Struts 1.2
     */
    protected void saveErrors(HttpServletRequest request, ActionMessages errors) {
        // Remove any error messages attribute if none are required
        if ((errors == null) || errors.isEmpty()) {
            request.removeAttribute(Globals.ERROR_KEY);

            return;
        }

        // Save the error messages we need
        request.setAttribute(Globals.ERROR_KEY, errors);
    }

    /**
     * <p>Save the specified messages keys into the appropriate request
     * attribute for use by the &lt;html:messages&gt; tag (if messages="true"
     * is set), if any messages are required. Otherwise, ensure that the
     * request attribute is not created.</p>
     *
     * @param request  The servlet request we are processing.
     * @param messages The messages to save. <code>null</code> or empty
     *                 messages removes any existing ActionMessages in the
     *                 request.
     * @since Struts 1.1
     */
    protected void saveMessages(HttpServletRequest request,
        ActionMessages messages) {
        // Remove any messages attribute if none are required
        if ((messages == null) || messages.isEmpty()) {
            request.removeAttribute(Globals.MESSAGE_KEY);

            return;
        }

        // Save the messages we need
        request.setAttribute(Globals.MESSAGE_KEY, messages);
    }

    /**
     * <p>Save the specified messages keys into the appropriate session
     * attribute for use by the &lt;html:messages&gt; tag (if messages="true"
     * is set), if any messages are required. Otherwise, ensure that the
     * session attribute is not created.</p>
     *
     * @param session  The session to save the messages in.
     * @param messages The messages to save. <code>null</code> or empty
     *                 messages removes any existing ActionMessages in the
     *                 session.
     * @since Struts 1.2
     */
    protected void saveMessages(HttpSession session, ActionMessages messages) {
        // Remove any messages attribute if none are required
        if ((messages == null) || messages.isEmpty()) {
            session.removeAttribute(Globals.MESSAGE_KEY);

            return;
        }

        // Save the messages we need
        session.setAttribute(Globals.MESSAGE_KEY, messages);
    }

    /**
     * <p>Save the specified error messages keys into the appropriate session
     * attribute for use by the &lt;html:messages&gt; tag (if
     * messages="false") or &lt;html:errors&gt;, if any error messages are
     * required. Otherwise, ensure that the session attribute is empty.</p>
     *
     * @param session The session to save the error messages in.
     * @param errors  The error messages to save. <code>null</code> or empty
     *                messages removes any existing error ActionMessages in
     *                the session.
     * @since Struts 1.3
     */
    protected void saveErrors(HttpSession session, ActionMessages errors) {
        // Remove the error attribute if none are required
        if ((errors == null) || errors.isEmpty()) {
            session.removeAttribute(Globals.ERROR_KEY);

            return;
        }

        // Save the errors we need
        session.setAttribute(Globals.ERROR_KEY, errors);
    }

    /**
     * <p>Save a new transaction token in the user's current session, creating
     * a new session if necessary.</p>
     *
     * @param request The servlet request we are processing
     */
    protected void saveToken(HttpServletRequest request) {
        token.saveToken(request);
    }

    /**
     * <p>Set the user's currently selected <code>Locale</code> into their
     * <code>HttpSession</code>.</p>
     *
     * @param request The request we are processing
     * @param locale  The user's selected Locale to be set, or null to select
     *                the server's default Locale
     */
    protected void setLocale(HttpServletRequest request, Locale locale) {
        HttpSession session = request.getSession();

        if (locale == null) {
            locale = Locale.getDefault();
        }

        session.setAttribute(Globals.LOCALE_KEY, locale);
    }
}
分享到:
评论

相关推荐

    struts2-json-plugin源码

    1. **Action结果类型**:在Struts2中,Action的结果类型决定了如何处理Action的返回值。`struts2-json-plugin`添加了JSON结果类型,当Action返回此类型时,会将结果转换为JSON格式。 2. **JSONResult类**:这是实现...

    struts2-core-2.0.11源码

    1. **拦截器(Interceptors)**:Struts2的核心特性之一,拦截器负责在Action调用前后执行额外的逻辑,如日志记录、权限验证等。在`org.apache.struts2.interceptor`包下,你可以找到各种预定义的拦截器类。 2. **...

    struts2-core-2.3.7源码

    通过深入研究`struts2-core-2.3.7`源码,我们可以了解Struts2如何处理请求,执行Action,应用拦截器,以及如何返回结果到客户端。这有助于我们理解其工作原理,优化性能,解决bug,甚至开发自己的插件。 学习源码时...

    struts-xwork-core源码

    Struts-xwork-core是Struts2框架的核心组件,它提供了Action和结果的执行模型,以及类型转换、数据验证和国际化等功能。在这个压缩包中,包含了该核心库的源代码,对于学习和理解Struts2的工作原理及其内部机制极具...

    struts in action 源码-2

    通过研究"Struts in Action 源码-2",开发者能够了解如何在实际项目中配置和使用Struts框架,以及如何组织和编写Action、Form Bean、配置文件等。此外,它还展示了如何利用Struts实现业务逻辑、数据验证、错误处理等...

    struts2-core-2.1.8.1 xwork-core-2.1.6源码

    1. **Action调度**:Struts2的核心在于Action类,它是业务逻辑的入口点。在`xwork-core-2.1.6`中,Action的调度机制是由`ActionInvocation`实现的,它负责调用Action的各个方法并管理拦截器链。`ActionProxy`则负责...

    Struts学习----Action 的配置和使用(源码学习)

    本文将深入探讨Struts Action的配置和使用,以及如何通过源码学习来提升对Struts的理解。 首先,Action配置主要在Struts配置文件(struts-config.xml)中进行。这个文件定义了应用程序的行为,包括Action的映射、...

    SSH\\others\\struts2-spring-plugin-2.2.1.jar

    `struts.spring.action扫描`定义了Action类的包扫描路径。`SpringPlugin`的配置指定了Spring应用上下文的位置。 在Spring的`applicationContext.xml`文件中,我们需要定义Action类的bean,这样它们就可以被Struts2...

    Struts高级源码11-21

    在深入理解Struts的高级源码时,我们需要先了解其基本原理和核心组件。Struts 2是Struts框架的升级版本,它结合了WebWork的核心功能,提供了更强大的功能和灵活性。 在描述中提到的"Struts高级源码11-21"可能是指一...

    源码:struts-kisso375-demo.rar

    3. **整合拦截器**:在Struts的配置文件(如struts.xml)中,添加Kisso的拦截器,使得每次请求在到达Action之前先经过Kisso的认证和授权检查。 4. **登录与权限控制**:Kisso提供了一系列API,用于处理用户的登录、...

    struts2-core-2.2.1 jar下载、源码下载 非常全面!!绝对可用!! 所需资源分最少。

    `struts2-core-2.2.1`源码可以帮助开发者查看和学习Struts2的核心代码,理解其内部机制,如Action、Interceptor、Result等概念,以及它们如何协同工作以实现HTTP请求的处理和视图的渲染。 API文档是框架的重要组成...

    struts-2.5.16-源码+示例(S2-057漏洞演示环境)

    而`struts-2.5.16-src.zip`则是源码包,对于开发者来说,深入研究源码有助于理解和解决类似的安全问题。 为了搭建S2-057漏洞的演示环境,你需要先解压这两个文件,然后按照Struts 2的官方文档配置项目。通常,这...

    struts源码+struts-lib

    1. **ActionServlet**:这是Struts框架的核心控制器,负责接收HTTP请求,解析请求参数,并调用相应的Action来处理业务逻辑。 2. **Action**:Action是处理业务逻辑的类,它继承自org.apache.struts.action.Action。...

    struts2-core-2.1.8.1.jar

    Struts2是一个非常著名的Java ...开发者可以利用Struts2的Action、Interceptor、Result等机制,结合Apache Commons库和FreeMarker模板引擎,轻松地管理业务逻辑、处理用户输入、呈现视图,从而提高开发效率和应用质量。

    struts框架入门学习---工程源码

    总结来说,这个“Struts框架入门学习---工程源码”提供了实践Struts框架的基础,涵盖了Action、MVC模式、配置文件、拦截器和视图等方面,对于初学者来说是一份宝贵的资料。通过分析和运行这个工程,你可以更好地理解...

    struts-1.2.9-src源码类库

    总的来说,"struts-1.2.9-src"源码库是学习和研究Struts框架的经典资料,通过阅读和分析,开发者可以更好地掌握Java Web开发,特别是Struts框架的应用技巧和内部机制,为实际项目开发提供坚实的理论基础和技术支持。

    深入浅出Struts2源码-例子程序(完整版)

    1. **Action与拦截器**:在Struts2中,Action是业务逻辑的载体,而拦截器则实现了对Action调用的预处理和后处理,如登录验证、日志记录等。通过自定义拦截器,开发者可以扩展框架功能。 2. **配置机制**:Struts2的...

    struts2 最新漏洞 S2-016、S2-017修补方案 .docx

    这个方案是通过重写 Struts2 的 DefaultActionMapper 的 handleSpecialParameters 方法,增加 action、redirect、redirectAction 等参数的过滤,以防止攻击者 inject 恶意代码。操作步骤如下: 1. 新建 ...

    struts2-2.2.3-all.zip

    通过研究这些样例,开发者可以学习到如何配置Struts2、如何编写Action类、如何使用不同的插件等。 ### Struts2_API Struts2_API文档是开发人员不可或缺的重要资源之一,它详细介绍了Struts2框架中的各个组件、类和...

    struts-2.3.32-src源码包

    深入研究Struts2.3.32源码包,开发者可以了解其内部工作机制,包括请求的处理流程、拦截器的调用顺序、组件的生命周期等,这对于优化性能、解决疑难问题或开发自定义扩展具有重要意义。同时,这也为学习其他Java Web...

Global site tag (gtag.js) - Google Analytics