美文网首页
struts1源码、示例、工作流程及原理浅析

struts1源码、示例、工作流程及原理浅析

作者: 鲨鱼爱吃蔬菜 | 来源:发表于2020-06-07 13:58 被阅读0次

MVC Struts是一个Java Web MVC开发框架。MVC早在1978年就作为Smalltalk的一种设计模式被提出来了,引用到Web应用中来时:模型Model用于封装与业务逻辑相关的数据和数据处理方法视图View是数据的HTML展现控制器Controller负责响应请求,协调Model和ViewModel,View和Controller的分开,是一种典型的关注点分离的思想,不仅使得代码复用性和组织性更好,使得Web应用的配置性和灵活性更好。MVC开发模式下,Java Web开发会遇到URL路由、模板渲染、表单绑定/提交/验证、Session封装、权限验证、国际化等一系列通用的问题,而MVC框架会将这些通用问题都封装进框架中,你在应用中根据自己的场景进行简单的配置和编码即可,MVC框架就能帮你处理好一切,可以极大地简化代码。


Struts1

Struts工作流程

首先初始化,读取配置(初始化ModuleConfig对象):ActionServlet是struts框架的总控制器,同时它也是一个Servlet,需要在web.xml中配置成自动启动。这样在web应用程序部署到服务器上以后,ActionServlet将自动初始化,它的主要任务就是读取struts的配置文件(struts-config.xml)的配置信息,而struts-config.xml是struts中核心的配置文件,在这个文件中配置了用户请求URL和控制器Action的映射关系,ActionServlet通过这个配置文件把用户的请求发送到对应的控制器中; 并且为不同的struts模块初始化相应的ModuleConfig对象(包括ActionConfig、ControlConfig、FormBeanConfig、ForwardConfig、MessageResourcesConfig)。


public void init() throws ServletException {
 
    // 此处省略了方法前后的异常处理
    // 第一阶段,准备阶段
    initInternal();
    initOther();
    initServlet();
    
    // 第二阶段, 默认模块配置解析
    getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
    initModuleConfigFactory();
    // Initialize modules as needed
    ModuleConfig moduleConfig = initModuleConfig("", config);
 
    // 第三阶段,默认模块组件初始化
    initModuleMessageResources(moduleConfig);
    initModuleDataSources(moduleConfig);
    initModulePlugIns(moduleConfig);
    moduleConfig.freeze();
 
    // 第四阶段, 自定义模块初始化
    Enumeration names = getServletConfig().getInitParameterNames();
    while (names.hasMoreElements()) {
        String name = (String) names.nextElement();
        if (!name.startsWith("config/")) {
            continue;
        }
        String prefix = name.substring(6);
        moduleConfig = initModuleConfig
            (prefix, getServletConfig().getInitParameter(name));
        initModuleMessageResources(moduleConfig);
        initModuleDataSources(moduleConfig);
        initModulePlugIns(moduleConfig);
        moduleConfig.freeze();
    }
 
    // 第五阶段,收尾阶段
    this.initModulePrefixes(this.getServletContext());
    this.destroyConfigDigester();
 
}

<struts-config>
    <form-beans>
        <form-bean name="registerForm" type="cn.liayun.web.formbean.RegisterFormBean"></form-bean>
    </form-beans>

    <!-- Struts1在调用RegisterAction的时候,它会把所有<action>...</action>中的配置信息封装到ActionMapping对象中 -->
    <action-mappings>            <!-- Struts1收到register请求的时候,将把请求中的所有数据封装到registerForm对象中 -->
        <action path="/register" 
                name="registerForm" 
                type="cn.liayun.web.action.RegisterAction"
                scope="request"
                attribute="liayun"
                parameter="method">
            <forward name="message" path="message.jsp" />
        </action>
        
        <action path="/registerUI" forward="/register.jsp"></action>
        
        <action path="/error" unknown="true" forward="/WEB-INF/jsp/error.jsp"></action>
    </action-mappings>
    
    <!-- 配置请求处理器(来处理请求),Struts1.2采用的请求处理器是RequestProcessor -->
    <controller processorClass="org.apache.struts.action.RequestProcessor"></controller>
</struts-config>

在struts web应用程序中,当web应用程序启动的时候,就会初始化ActionServlet在初始化ActionServlet的时候会加载struts-config.xml配置文件,在加载成功后会把这些URL和控制器映射关系存放在ActionMapping对象或者其他对象中。当ActionServlet接收到用户请求的时候,就会按照下面的流程对用户请求进行处理。


image.png

(1)ActionServlet接收到用户的请求后,会根据请求URL寻找匹配的ActionMapping对象,如果匹配失败,说明用户请求的URL路径信息有误,所以返回请求路径无效的信息,当找到匹配的ActionMapping的时候,进入到下一步。

(2)当ActionServlet找到匹配的ActionMapping对象的时候,会根据ActionMapping中的映射信息判断对应的ActionForm对象是否存在,如果不存在对应的ActionForm对象就创建一个新的ActionForm对应,并把用户提交的表单信息保存到这个ActionForm对象中。

//actionform示例
      public class AddStudentForm extends ActionForm {
          private String name;
          private String major;
          private float score;
          private Date birth;
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public String getMajor() {
              return major;
          }
          public void setMajor(String major) {
              this.major = major;
          }
          public float getScore() {
              return score;
          }
          public void setScore(float score) {
              this.score = score;
          }
          public Date getBirth() {
              return birth;
          }
          public void setBirth(Date birth) {
              this.birth = birth;
          }
      }

(3)在struts-config.xml中这个配置文件,可以配置表单是否需要验证,如果需要验证,就调用ActionForm中的validate()方法对用户输入的表单进行验证。

(4)如果ActionForm的validate()方法返回了ActionErrors对象,则表明验证失败,ActionServlet把这个页面返回到用户输入的界面,提示用户重新输入。如果方法的返回值为null,就表明验证已经通过,可以进入下一步处理。

(5)ActionServlet可以根据ActionMapping对象查找用户请求转发给哪个控制器Action,如果对应的Action对象不存在,就创建这个对象,并调用这个Action的excute()方法。具体 Action 类的功能一般都在 execute方法中完成。

//execute方法示例
      AddStudentForm addStu = (AddStudentForm)form;
      IStudentDAO stuDAO = new StudentDAO();
      boolean successful = false;
      successful = stuDAO.addStudent(addStu);
      if(successful)
          return mapping.findForward("addSuccess");
      else
          return mapping.findForward("addFailure");   

(6)业务逻辑控制器Action的execute()方法就会返回一个ActionForward对象,ActionServlet把控制器处理的结果转发到ActionForward对象指定的JSP页面。

action配置示例
<form-bean name="addStuForm" type="com.yxb.struts.AddStudentForm"></form-bean>
      <action path="/addStu.do"
          type="com.yxb.struts.AddStudentAction"
          name="addStuForm">
              <forward name="addSuccess" path="/add_success.jsp"></forward>
              <forward name="addFailure" path="/add_failure.jsp"></forward>
      </action>

(7)ActionForward对象指定的JSP页面根据返回的处理结果,用合适形式把服务器处理的结果展示给用户,到这里为止,一个客户请求的整个过程完毕。

Struts1 MVC结构流程

总结:

  • 整个struts的开发满足了标准的MVC处理结构,结构严谨,但是这种实现方式也存在一定的历史局限性;也在初期的ActionForm设计上出现了设计失误;
  • 随着项目开发的进行,在struts开发里面一定会存在多个Action,但是每一个Action都必须有一个与之对应的ActionForm绑定,那么开发的代码量非常大。
  • Actionform需要编写验证操作,如果分开写那么所面临的问题是百分之九十的代码是重复的;所有要使用的Action和ActionForm需要在struts-config.xml里进行定义,如果涉及工程量大的项目,配置文件一大,在做修改的时候就有可能出现错乱;

相关文章

网友评论

      本文标题:struts1源码、示例、工作流程及原理浅析

      本文链接:https://www.haomeiwen.com/subject/twzbzhtx.html