`

Action类

阅读更多
Action类是用户请求和业务逻辑之间的桥梁,每个Action充当客户的一项业务代理。在RequestProcessor类预处理请求时,在创建了Action的实例后,就调用自身的processActionPerform()方法,该方法在调用Action类的execute()。
Action的excute()方法调用模型的业务方法,完成用户请求,然后根据执行结果把请求转发给其他合适的WEB组件。

一、Action类缓存

struts应用的生命周期中RequestProcessor只保证一个Action实例,所有的客户请求都共享这个实例.所有请求可以同时执行它的excute()方法。RequestProcessor类包含一个HashMap,作为存放所有Action实例的缓存。每个Action实例在缓存中存放的key为Action类名。在RequestProcessor类的processActionCreate()方法中,首先检查在HashMap中是否存在Action实例,如果有直接使用,否则创建一个新的。创建Action实力的代码位于同步代码块中,以保证只有一个线程创建Action实例,然后放在HashMap中。供其他线程使用。
如下代码
Java代码 复制代码
  1. protected Action processActionCreate(HttpServletRequest request,   
  2.                                        HttpServletResponse response,   
  3.                                        ActionMapping mapping)   
  4.       throws IOException {   
  5.   
  6.       // Acquire the Action instance we will be using (if there is one)   
  7.       String className = mapping.getType();   
  8.       if (log.isDebugEnabled()) {   
  9.           log.debug(" Looking for Action instance for class " + className);   
  10.       }   
  11.   
  12.       // :TODO: If there were a mapping property indicating whether   
  13.       // an Action were a singleton or not ([true]),   
  14.       // could we just instantiate and return a new instance here?   
  15.   
  16.       Action instance = null;   
  17.       synchronized (actions) {   
  18.   
  19.           // Return any existing Action instance of this class   
  20.           instance = (Action) actions.get(className);   
  21.           if (instance != null) {   
  22.               if (log.isTraceEnabled()) {   
  23.                   log.trace("  Returning existing Action instance");   
  24.               }   
  25.               return (instance);   
  26.           }   
  27.   
  28.           // Create and return a new Action instance   
  29.           if (log.isTraceEnabled()) {   
  30.               log.trace("  Creating new Action instance");   
  31.           }   
  32.              
  33.           try {   
  34.               instance = (Action) RequestUtils.applicationInstance(className);   
  35.               // :TODO: Maybe we should propagate this exception   
  36.               // instead of returning null.   
  37.           } catch (Exception e) {   
  38.               log.error(   
  39.                   getInternal().getMessage("actionCreate", mapping.getPath()),   
  40.                   e);   
  41.                      
  42.               response.sendError(   
  43.                   HttpServletResponse.SC_INTERNAL_SERVER_ERROR,   
  44.                   getInternal().getMessage("actionCreate", mapping.getPath()));   
  45.                      
  46.               return (null);   
  47.           }   
  48.              
  49.           instance.setServlet(this.servlet);   
  50.           actions.put(className, instance);   
  51.       }   
  52.   
  53.       return (instance);   
  54.   
  55.   }  
  protected Action processActionCreate(HttpServletRequest request,
                                         HttpServletResponse response,
                                         ActionMapping mapping)
        throws IOException {

        // Acquire the Action instance we will be using (if there is one)
        String className = mapping.getType();
        if (log.isDebugEnabled()) {
            log.debug(" Looking for Action instance for class " + className);
        }

        // :TODO: If there were a mapping property indicating whether
        // an Action were a singleton or not ([true]),
        // could we just instantiate and return a new instance here?

        Action instance = null;
        synchronized (actions) {

            // Return any existing Action instance of this class
            instance = (Action) actions.get(className);
            if (instance != null) {
                if (log.isTraceEnabled()) {
                    log.trace("  Returning existing Action instance");
                }
                return (instance);
            }

            // Create and return a new Action instance
            if (log.isTraceEnabled()) {
                log.trace("  Creating new Action instance");
            }
            
            try {
                instance = (Action) RequestUtils.applicationInstance(className);
                // :TODO: Maybe we should propagate this exception
                // instead of returning null.
            } catch (Exception e) {
                log.error(
                    getInternal().getMessage("actionCreate", mapping.getPath()),
                    e);
                    
                response.sendError(
                    HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                    getInternal().getMessage("actionCreate", mapping.getPath()));
                    
                return (null);
            }
            
            instance.setServlet(this.servlet);
            actions.put(className, instance);
        }

        return (instance);

    }


二.创建支持多线程的Action
1.什么是线程安全的代码
在多线程环境下能正确执行的代码就是线程安全的。
安全的意思是能正确执行,否则后果是程序执行错误,可能出现各种异常情况。

2.如何编写线程安全的代码
很多书籍里都详细讲解了如何这方面的问题,他们主要讲解的是如何同步线程对共享资源的使用的问题。主要是对synchronized关键字的各种用法,以及锁的概念。
Java1.5中也提供了如读写锁这类的工具类。这些都需要较高的技巧,而且相对难于调试。

但是,线程同步是不得以的方法,是比较复杂的,而且会带来性能的损失。等效的代码中,不需要同步在编写容易度和性能上会更好些。
我这里强调的是什么代码是始终为线程安全的、是不需要同步的。如下:
1)常量始终是线程安全的,因为只存在读操作。
2)对构造器的访问(new 操作)是线程安全的,因为每次都新建一个实例,不会访问共享的资源。
3)最重要的是:局部变量是线程安全的。因为每执行一个方法,都会在独立的空间创建局部变量,它不是共享的资源。局部变量包括方法的参数变量。

Servlet是在多线程环境下的。即可能有多个请求发给一个servelt实例,每个请求是一个线程。 struts下的action也类似,同样在多线程环境下,你也必须编写线程安全的Action类。
保证线程安全的原则就是仅仅使用局部变量,谨慎使用实例变量(拥有状态的实例,尤其是拥有业务对象状态的实例). 如果要用到那些有状态的实例,唯一和最好的办法是在Action类中,仅仅在Action类的execute()方法中使用局部变量,对于每个调用execute()方法的线程,JVM会在每个线程的堆栈中创建局部变量,因此每个线程拥有独立的局部变量,不会被其他线程共享.当线程执行完execute()方法后,它的局部变量就会被销毁.
如果Action类的实例变量是必须的话,需要采用JAVA同步机制(synchronized)对访问共享资源的代码块进行同步


三、Struts的几种Action
Struts提供了一些现成的Action类,直接使用可以大大节省时间,如下
ForwardAction
可以转发到其他web组件,仅仅提供一个转发功能,不作处理。
IncludeAction
包含其他web组件。
DiapatchAction
通常一个Action只完成一个操作,用这个Action可以完成一组相关的操作。
LookupDispatchAction
他是DiapatchAction的子类,也可以定义多个方法,但主要用于一个表单里有多个按钮,而这些按钮又有一个共同的名字的场合。
SwitchAction
用于子模块之间的切换。


四.ActionForward类
Action类的excute()方法返回一个ActionForward对象,它代表了web资源的逻辑抽象,这里的web资源可以是jsp页面、Java servlet、或Action。
从excute返回ActionForward可以有两种方法。
1) 动态创建一个ActionForward实例
return new ActionForward(”Failure”,”login.jsp”,true);
2) 调用ActionMappin实例的findForward方法
这个方法先从action级别找,然后在<global-forwards />级别找
return mapping.findForward(“Failure”);
分享到:
评论

相关推荐

    EXTJS4.0视频教程配套代码包含action类

    这个视频教程配套代码主要涉及EXTJS4.0中的action类,这是EXTJS中处理服务器端交互的关键部分。在EXTJS中,action类通常指的是Ext.Ajax或Ext.data.proxy.Ajax,它们负责发送异步请求到服务器并处理响应。 在EXTJS...

    重新封装struts中action类

    `重新封装struts中action类`这个主题主要涉及的是对Struts中默认的`Action`类进行扩展和优化,以便更好地满足项目需求。在描述中提到的封装主要目标是屏蔽`ActionMapping`对象,使得子类化的`Action`类中的方法只...

    struts2一个action处理多个请求 struts2实例

    在Struts2框架中,Action类是业务逻辑处理的核心组件,它负责接收并处理来自用户的请求。本实例探讨了如何让一个Action类处理多个请求,这在开发中常见于需要集中处理相似请求的情况,可以提高代码复用性和结构的...

    一个Action对应多个类实例。

    在这个框架中,Action类扮演着控制器的角色,负责接收用户请求,处理业务逻辑,并将结果传递给视图进行展示。 **1. Action类的角色** Action类是Struts框架的核心组件,它处理用户的请求并控制应用的行为。一个...

    action登陆实现,获取web元素

    在这个场景中,"action登陆实现,获取web元素"指的是通过Action类来实现用户登录功能,并在登录过程中与Web页面上的元素进行交互。 首先,我们来详细探讨Action类的使用。Action类是业务逻辑的载体,它接收来自...

    struts2例子中的action类

    很经典的struts2开发实例,其中的action类的写法可以教你很清楚的了解具体的调用过程回给你开发带来很大的帮助

    自定义Action继承ActionSupport实现简单登录

    在Struts2框架中,自定义Action类是处理用户请求的核心组件。`ActionSupport`是Struts2提供的一种基础Action类,它包含了多种内置功能,如国际化、异常处理和校验支持等。当我们需要实现一个特定的功能,比如这里的...

    Junit测试Action

    【标题】"Junit测试Action"涉及的是在Java开发中使用JUnit进行Action类的单元测试。JUnit是一款广泛使用的Java编程语言的单元测试框架,它使得开发者能够方便地编写和执行测试用例,确保代码的质量和功能的正确性。 ...

    struts的一个Action类。

    基于web开发的struts应用的一个action代码,帮助初学者学习参考,希望有所帮助。

    Action——Action的配置和作用

    此外,Action类在处理请求时,还可以作为数据传输的中介,通过定义属性和提供getter、setter方法,Action类允许页面部分获取和提交数据。 我们还必须要讨论Action的配置。Action的配置通常在struts.xml文件中进行。...

    用MockStrutsTestCase测试action测试类

    在Struts框架中,Action类是核心组件,负责处理用户请求并调用业务逻辑。为了确保Action类的正确性和可靠性,开发者通常会进行单元测试。MockStrutsTestCase是Apache Struts提供的一个专用测试工具,它允许开发者...

    基于用户登陆的struts2中action的分类实例

    一个Action类通常对应一个具体的业务操作,比如登录、注册、修改个人信息等。它继承自`com.opensymphony.xwork2.ActionSupport`类或其子类,并重写`execute()`方法,这是处理请求的核心部分。Struts2通过配置文件...

    自定义Action实现Action接口(实现简单登录功能)

    首先,我们需要理解Struts2的架构和Action类的角色。 Struts2是一个基于MVC(Model-View-Controller)设计模式的Java Web框架。它提供了一种组织应用程序的方式,使得代码结构清晰,易于维护。在Struts2中,Action...

    Struts2学习教程之Action类如何访问WEB资源

    在Struts2中,Action类是核心组件,它处理用户请求并控制应用程序的流程。本教程将深入讲解如何在Struts2的Action类中访问Web资源,如HttpServletRequest、HttpServletResponse和ServletContext。 首先,Web资源在B...

    ActionServlet demo

    当用户提交表单或点击链接时,请求会被发送到ActionServlet,它解析请求参数,根据配置的Action Mapping找到对应的Action类,然后调用该Action的execute()方法执行业务逻辑。ActionServlet是Struts的核心,它将用户...

    java-action.rar_action

    在Java Web开发框架中,如Struts和Spring MVC,Action类扮演着控制器的角色。标题"java-action.rar_action"中的"Action"通常指的是这样的控制器类。这类类负责接收用户的请求,处理业务逻辑,然后将结果传递给视图层...

    struts2.0之action

    在Struts 1.x中,Action类需要继承`org.apache.struts.action.Action`或其子类,同时表单数据会封装在FormBean中。而Struts 2.0则更加灵活,Action类不再需要强制继承特定的类或实现特定的接口。表单数据直接包含在...

    多action之间跳转传参问题

    在Struts2框架中,Action类是业务逻辑的载体,它负责接收用户的请求,处理业务逻辑,并返回相应的结果。当需要在多个Action之间跳转时,我们需要考虑如何在Action之间传递数据,以便后续的Action可以继续处理或展示...

    Struts 2.0的Action讲解

    与Struts 1.x相比,Struts 2.0的Action模型更加灵活,不再强制要求Action类必须继承特定的基类或实现特定接口。 在Struts 2.0中,Action类可以完全自定义,但为了方便开发,通常我们会选择继承`...

Global site tag (gtag.js) - Google Analytics