`

剖析Struts1中的五个对象

 
阅读更多

Struts是一个基于MVC架构的框架(框架实现了某些领域通用完备功能的底层服务),它主要用于开发Web应用程序,帮助我们减少了用MVC开发Web应用的时间,简化了开发过程,使开发更具模块化、灵活性和重用性。可以说Struts把MVC的设计思想发挥到了极致,尤其在Controller层。

在用Struts开发项目直接接触的有这么几个类:ActionMapping、ActionServlet、ActionForm、Action和ActionForward,这五个类各司其职,使上有老下有小的Controller层接近完美。因Struts是面向对象设计,掌握了这几个类,也就基本掌握了Struts的用法,下面按照这几个类的执行流程举例说明他们在Struts中的具体用法。下图为Struts的一个大致流程图:

这里不考虑各个对象的创建细节,单从工作的流程分析各个类的作用。

   ActionServlet


客户端向服务器(Tomcat)发起请求,通过在web.xml中的配置,请求直接进入ActionServlet,从命名就可以看出这是一个Servlet,此类是不需要我们显式去创建的,Struts框架已对它做了实现。请求继续调用ActionServlet的doGet/doPost方法,实际上这个两个方法共同调用了RequestProcess类的process方法,process方法才是真正的核心,在process方法中,通过调用processPtah方法截取Request中传递过来的URL,然后调用processMapping方法根据截取的URL取得相应的ActionMapping。

在web.xml中的配置代码如下:

[html] view plaincopy
 
  1. <servlet>  
  2.   <servlet-name>action</servlet-name>  
  3.   <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>  
  4.   <init-param>  
  5.     <param-name>config</param-name>  
  6.     <param-value>/WEB-INF/struts-config.xml</param-value>  
  7.   </init-param>  
  8.   <init-param>  
  9.     <param-name>debug</param-name>  
  10.     <param-value>2</param-value>  
  11.   </init-param>  
  12.   <init-param>  
  13.     <param-name>detail</param-name>  
  14.     <param-value>2</param-value>  
  15.   </init-param>  
  16.   <load-on-startup>2</load-on-startup>  
  17. </servlet>  
  18. <servlet-mapping>  
  19.   <servlet-name>action</servlet-name>  
  20.   <url-pattern>*.do</url-pattern>  
  21. </servlet-mapping>  

从上面配置不难看出,ActionServlet在Tomcat启动时,就已经创建好了,只要是以do结尾的请求都会被ActionServlet拦截下来,然后它将不同的请求转发给对应的Action对象,让Action进一步处理客户端的请求。因此ActionServlet肩负着中央控制器角色,是Struts的核心。下面介绍的各个类中,依旧会看到ActionServlet的影子。

  ActionMapping


ActionServlet调用processMapping方法,此方法首先会调用moduleConfig.findActionConfig(path),获取对应的ActionMapping对象。Struts框架将核心配置文件struts-config.xml解析并放入了ActionMapping对象里。

等返回ActionMapping对象后,processMapping方法把ActionMapping设置到Request或Session中方便后面其他地方的使用,体现了面向对象封装的好处。struts-config.xml配置信息如下:

[html] view plaincopy
 
  1. <struts-config>  
  2.     <form-beans>  
  3.         <form-bean name="itemForm" type="com.snail.drp.web.forms.ItemActionForm"/>  
  4.     </form-beans>  
  5.       
  6.     <global-exceptions>  
  7.         <exception key="errors.detail" type="com.snail.drp.AppException" path="/error.jsp"/>  
  8.     </global-exceptions>  
  9.        
  10.     <action-mappings>  
  11.         <action path="/item"  
  12.                 type="com.snail.drp.web.actions.ItemAction"  
  13.                 name="itemForm"  
  14.                 scope="request"  
  15.                 parameter="command"  
  16.                 >  
  17.             <forward name="list" path="/WEB-INF/jsp/item_maint.jsp"/>   
  18.             <forward name="show_add" path="/WEB-INF/jsp/item_add.jsp"/>     
  19.             <forward name="item_index" path="item.do" redirect="true"/>  
  20.             <forward name="show_modify" path="/WEB-INF/jsp/item_modify.jsp"/>  
  21.             <forward name="show_detail" path="/WEB-INF/jsp/item_detail.jsp"/>  
  22.             <forward name="show_upload" path="/WEB-INF/jsp/item_upload.jsp"/>  
  23.         </action>  
  24.     </action-mappings>  
  25.     <message-resources parameter="MessageResources"/>  
  26. </struts-config>  

配置信息里看出,其中中包含有与请求对应的ActionForm、Action、ActionForward、错误处理以及国际化等配置信息,这些都可以通过ActionMapping取出来。

 

  ActionForm


processMapping方法生命周期结束后,ActionServlet继续调用processForm方法。ProcessForm方法根据ActionMapping中的name名称查找ActionForm,如果配置了ActionForm,那么就到request或session中查找,如果在request或session中存在已经创建的ActionForm,那么将返回。如果不存在那么会根据ActionForm的完成路径采用反射进行创建,再将创建好的ActionForm放到request或session中,方便后面的读取。

创建好ActionForm对象后,接下来就要该给ActionForm中赋值了,此时,ActionServlet会调用processPopulate方法,首先执行ActionForm中的reset方法进行重置,然后得到表单中所有输入域的name名称,再调用request.getParameterValues(),根据name名称得到相应的值,最后将表单中的数据全部放到一个map中,map的key为表单输入域的名称,map的value为表单输入域的值(字符串数组),接下来调用一个第三方组件BeanUtils,将Map中的值,根据ActionForm中的类型先转换好,再调用ActionForm中的setter方法设置到ActionForm上。

唯一要我们做的是创建一个类,然后让它继承ActionForm,根据表单输入域的name提供get和set方法,并在Struts-Config.xml中配置(参见上一篇)。ActionForm代码如下:

[java] view plaincopy
 
  1. package com.snail.drp.web.forms;  
  2.   
  3. import org.apache.struts.action.ActionForm;  
  4. import org.apache.struts.upload.FormFile;  
  5.   
  6. public class ItemActionForm extends ActionForm {  
  7.   
  8.     private String itemNo;  
  9.       
  10.     private String itemName;  
  11.   
  12.     public String getItemNo() {  
  13.         return itemNo;  
  14.     }  
  15.   
  16.     public void setItemNo(String itemNo) {  
  17.         this.itemNo = itemNo;  
  18.     }  
  19.   
  20.     public String getItemName() {  
  21.         return itemName;  
  22.     }  
  23.   
  24.     public void setItemName(String itemName) {  
  25.         this.itemName = itemName;  
  26.     }  
  27.   
  28. }  

那么一个完整的ActionForm就创建好了,类型转换等工作它也为我们完成了。接下来在Action中就可以任意调用了。其实,ActionForm非常类似于Domain模型中的JavaBean,他和表单中的输入域形成映射关系,将输入域中的name和值通过Set方法放入Map中,其他地方可以通过get方法来获取。

  Action和DispatchAction


继续沿着ActionServlet前行,搞定ActionForm后,ActionServlet会调用processActionCreate方法,根据Action的完整类名称到ActionMapping中去查找,如果存在就返回Action对象,否则根据Action类的完整名称采用反射去创建,再将创建好的Action放到ActionMapping中,因此Struts1的Action是单实例的,存在线程安全问题。

然后ActionServlet调用processActionPerform方法,执行用户自定义的Action中的execute方法,将ActionMaping、ActionForm、request、response传递过去,将ActionForward对象返回。

Action是一个Java类,负责调用业务逻辑方法,检测处理异常,校验输入数据和根据逻辑进行转向,它一般按照职责划分,意味着职责的增多,Action类也会相应的增多,为了解决这种类过多的情况,由DispatchAction类代替Action,由它继承Action,把Action众多的类完成的功能放到了方法体中,因此可以在一个DispatchAction中处理多个Action所完成的事情,有效避免了类过多的弊病。代码如下:

[java] view plaincopy
 
  1. package com.snail.drp.web.actions;  
  2.   
  3. import java.io.FileOutputStream;  
  4. import java.util.List;  
  5. import javax.servlet.http.HttpServletRequest;  
  6. import javax.servlet.http.HttpServletResponse;  
  7.   
  8. import org.apache.commons.beanutils.BeanUtils;  
  9. import org.apache.struts.action.ActionForm;  
  10. import org.apache.struts.action.ActionForward;  
  11. import org.apache.struts.action.ActionMapping;  
  12. import org.apache.struts.actions.DispatchAction;  
  13. import org.apache.struts.upload.FormFile;  
  14.   
  15. import com.snail.drp.BeanFactory;  
  16. import com.snail.drp.PageModel;  
  17. import com.snail.drp.domain.Item;  
  18. import com.snail.drp.domain.ItemCategory;  
  19. import com.snail.drp.domain.ItemUnit;  
  20. import com.snail.drp.service.DataDictService;  
  21. import com.snail.drp.service.ItemService;  
  22. import com.snail.drp.web.forms.ItemActionForm;  
  23.   
  24. public class ItemAction extends DispatchAction {  
  25.       
  26.     /** 
  27.      * 查找所有物料信息 
  28.      */  
  29.     @Override  
  30.     protected ActionForward unspecified(ActionMapping mapping, ActionForm form,  
  31.             HttpServletRequest request, HttpServletResponse response)  
  32.             throws Exception {  
  33.         ItemActionForm iaf = (ItemActionForm)form;   
  34.       
  35.         int pageSize = Integer.parseInt(request.getSession().getServletContext().getInitParameter("pageSize"));  
  36.         String queryString = iaf.getClientIdOrName();  
  37.         int pageNo = iaf.getPageNo();  
  38.         ItemService itemService = (ItemService)BeanFactory.getInstance().getBean(ItemService.class);  
  39.         PageModel pageModel =  itemService.findAllItem(queryString, pageNo, pageSize);  
  40.         request.setAttribute("pageModel", pageModel);  
  41.         return mapping.findForward("list");  
  42.     }  
  43.       
  44.     /** 
  45.      * 添加物料 
  46.      * @param mapping 
  47.      * @param form 
  48.      * @param request 
  49.      * @param response 
  50.      * @return 
  51.      * @throws Exception 
  52.      */  
  53.     public ActionForward add(ActionMapping mapping, ActionForm form,  
  54.             HttpServletRequest request, HttpServletResponse response)  
  55.             throws Exception {  
  56.           
  57.         ItemActionForm iaf = (ItemActionForm)form;  
  58.           
  59.         Item item = new Item();  
  60.           
  61.         BeanUtils.copyProperties(item, iaf);  
  62.           
  63.         ItemCategory itemCategory = new ItemCategory();  
  64.         itemCategory.setId(iaf.getCategory());  
  65.         item.setItemCategory(itemCategory);  
  66.           
  67.         ItemUnit itemUnit = new ItemUnit();  
  68.         itemUnit.setId(iaf.getUnit());  
  69.         item.setItemUnit(itemUnit);       
  70.           
  71.         ItemService itemService = (ItemService)BeanFactory.getInstance().getBean(ItemService.class);  
  72.         itemService.addItem(item);  
  73.         return mapping.findForward("item_index");  
  74.     }  
  75. }  

如果将以上代码继承自Action,那么该类必须重写execute方法,执行需要的功能也必须在execute方法中,这样如果不利用多态创建多个Action类,那就得需要很多if...else...语句,这种编码方式是不可取的。

  ActionForward

好了,终于能看到完整的图了。


其实从命名就可以看出ActionForward主要负责转向,执行完processActionPerform方法后,返回的就是ActionForward对象,ActionServlet紧接着调用processForwardConfig方法,根据ActionForward完成转向(转发或重定向)。ActionForward主要信息来自于ActionMapping对象,因此需要我们做的是配置好Struts-Config.xml文件即可。

这只是简单的分析了一下应用Struts的流程,要想真正的学习还需研究其源代码来的直接。

分享到:
评论

相关推荐

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用03

    4. 配置Struts2-Spring插件:这个插件允许Struts2的动作类直接在Spring容器中管理,避免了在Action类中手动装配依赖。 5. 实现业务逻辑:在Action类中,通过@Autowired注解或通过Spring的getBean方法获取由Spring...

    struts1,struts2,spring,hibernate

    Struts1、Struts2、Spring和Hibernate是Java Web开发中的四大框架,它们各自承担着不同的职责,共同构建了一个强大的企业级应用体系。 Struts1是Apache组织开发的一个开源MVC框架,它使得Java Web应用程序的开发...

    Struts2架构剖析

    ActionContext是每个Action执行的上下文环境,它包含了一组对象,如session、application、parameter等,这些都是Action在执行过程中可能需要的数据。ActionContext为Action提供了访问请求和会话数据的途径。 总的...

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用02

    这个"Struts2+Hibernate+Spring整合开发深入剖析与范例应用02"的学习资源,很可能是关于这三大框架集成使用的详细教程或案例集。02这个文件名可能代表系列的第二部分,意味着它可能在前一部分的基础上进一步深入讲解...

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用06

    在"Struts2+Hibernate+Spring整合开发深入剖析与范例应用06"中,我们可能涉及以下几个关键知识点: 1. **Struts2框架**:Struts2是一个强大的MVC框架,用于构建动态Web应用。它的核心是Action类,它处理HTTP请求并...

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用04

    在这个"Struts2+Hibernate+Spring整合开发深入剖析与范例应用04"的主题中,我们将探讨这三大框架的集成过程、关键概念以及实际应用。 首先,Struts2是基于MVC(Model-View-Controller)设计模式的Web框架,它负责...

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用05

    1. 用户发送请求到Struts2 Action,Action中通过@Autowired注解注入UserService。 2. UserService通过Spring的JdbcTemplate或Hibernate的SessionFactory执行SQL查询或持久化操作。 3. 数据库操作完成后,UserService...

    struts hibernate spring框架剖析

    随着信息技术的快速发展,Java Web开发领域中,Struts、Hibernate与Spring这三个框架因其在实际项目中的广泛应用而备受关注。本文将对这三个框架进行深入剖析,旨在为初学者提供一个全面的理解视角。 #### 二、...

    struts1.1源代码

    在 struts-config.xml 文件中,开发者可以定义多个 ActionMapping 条目,每个条目包含一个请求 URL 和对应处理该请求的 Action 类。 5. ActionForward: ActionForward 定义了请求处理后的跳转目标。当 Action 类...

    Struts2之拦截器原理分析及使用-上案例struts007

    本篇文章将深入剖析Struts2拦截器的工作原理,并通过案例"struts007"来展示如何实际应用。 首先,我们了解下拦截器的基本概念。拦截器是一个实现了Struts2提供的`Interceptor`接口的类,它定义了两个方法:`...

    struts2框架源码分析及问题汇总

    本文将深入剖析Struts2的源码,揭示其工作原理,并汇总常见问题,帮助开发者更好地理解和使用这个框架。 一、Struts2框架基础 1. 框架结构:Struts2的核心组件包括Action、Result、Interceptor(拦截器)等。...

    手动编写struts源码及讲解

    这个过程中,你不仅会学习到如何使用Struts,还能掌握面向对象设计原则、MVC模式、Servlet API等相关知识,对整个Web开发有更全面的认识。 在“MyStruts”这个压缩包中,可能包含的是整个项目的源码结构,包括...

    Struts2+Hibernate+Spring整合开发深入剖析与范例应用07

    Struts2、Hibernate和Spring是Java Web开发中的三大框架,它们各自在应用程序的不同层面发挥着重要作用。Struts2作为MVC(模型-视图-控制器)框架,负责处理用户请求和展示视图;Hibernate是一个对象关系映射(ORM)...

    hibernate+struts2 框架项目源代码

    《深入剖析Hibernate+Struts2框架项目源代码》 在当今的Java Web开发领域,Hibernate和Struts2是两个非常重要的开源框架。它们分别在持久层和MVC(Model-View-Controller)架构方面提供了强大的支持,使得开发者...

    Struts 2+Hibernate+Spring整合开发技术详解随书源码

    Struts 2、Hibernate 和 Spring 是Java开发中的三大框架,它们在企业级应用开发中扮演着重要的角色。Struts 2 提供了MVC(Model-View-Controller)设计模式的实现,帮助开发者构建可维护性和扩展性良好的Web应用程序...

    struts中文版教程

    5. **模型驱动和值栈**:讲解Struts 2中的值栈模型,如何将请求参数映射到Action对象的属性,以及如何从视图层获取数据。 6. **动态方法调用**:介绍Struts 2的动态方法调用特性,允许根据请求参数动态执行Action...

    Struts2权威指南

    Struts2是Java Web开发中的一个强大框架,它在经典的Struts1基础上进行了重大改进,提供了更灵活的架构和更好的性能。《Struts2权威指南》这本书深入剖析了这个框架,帮助开发者掌握其核心概念、设计模式以及最佳...

    孙卫琴-精通Struts源代码

    "孙卫琴-精通Struts源代码"这本书,通过深入剖析Struts的源代码,帮助读者理解并掌握这一框架的核心机制。 在Struts框架中,模型(Model)通常由业务逻辑组件(如EJB或POJOs)组成,负责处理数据和业务规则。视图...

    Struts在行动2

    本文将基于《Struts在行动2》中的核心章节内容,深入剖析Struts框架的基本原理、控制流程、以及其优势和局限性,旨在帮助开发者更好地理解和运用这一强大的Web应用框架。 #### 二、深入Struts架构 **2.1 Talking ...

Global site tag (gtag.js) - Google Analytics