struts1与struts2的对比学习

简介:

           struts2的出现必定有它的优势,而且他的市场现在已经远远的超过了struts1,那么在解释它的原理之前,我们首先来看一下struts2究竟有哪些优势呢?我们为什么要用struts2?

         1、用struts2的目的~~

          把请求和界面分开,struts框架具有组件的模块化,灵活性和重用性的优点,同时简化了基于MVC的web应用程序的开发。

          2、那么struts2有哪些优点呢?

            a.Struts框 架本身是使用Java Servlet和JavaServer Pages技术的一种Model-View-Controller(MVC)实现.通过使用Struts作为基础,开发者能够更专注于应用程序的商业逻辑。

            b.提供了对MVC的一个清晰的实现,这一实现包含了很多参与对所以请求进行处理的关键组件,如:使用OGNL进行参数传递、拦截器 、全局结果与声明式异常 、taglib等等。

          明确了这些优点,我们下面说说struts2的工作原理:

          在struts2的应用中,从用户请求到服务器返回相应响应给用户端的过程中,包含了许多组件如:Controller、ActionProxy、ActionMapping、Configuration Manager、ActionInvocation、Inerceptor、Action、Result等。

    

     (1)  客户端(Client)向Action发用一个请求(Request)

          (2)  Container(如Tomcat)通过web.xml映射请求,并获得控制器(Controller)的名字

    (3)  Container(如Tomcat)调用控制器(StrutsPrepareAndExecuteFilter或FilterDispatcher)。在Struts2.1以前调用FilterDispatcher,Struts2.1以后调用StrutsPrepareAndExecuteFilter,FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action。

       Struts 2框架由3个部分组成:核心控制器FilterDispatcher、业务控制器和用户实现的业务逻辑组件。在这3个部分里,Struts 2框架提供了核心控制器FilterDispatcher,而用户需要实现业务控制器和业务逻辑组件。 FilterDispatcher是控制器的核心,就是mvc中c控制层的核心。下面粗略的分析下我理解FilterDispatcher工作流程和原理:FilterDispatcher进行初始化并启用核心doFilter。该控制器作为一个Filter运行在Web应用中,它负责拦截所有的用户请求,当 用户请求到达时,该Filter会过滤用户请求。如果用户请求以action结尾,该请求将被转入Struts 2框架处理。      

package com.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class Myfilter implements Filter {

	@Override
	public void destroy() {
		System.out.println("------Myfilter.destroy()----------");

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		System.out.println("------Myfilter.doFilter()----------");
		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		config.getInitParameter("encoding");
		System.out.println("------Myfilter.init()----------");

	}

}
       (4)(5)、如果ActionMapper决定需要调用某个Action,FilterDispatcher把请求的处理交给ActionProxy。

            (6)、ActionProxy通过ConfigurationManager询问框架的配置文件,找到需要调用的Action类 ,这里,我们一般是从struts.xml配置中读取。      

<action name="login" class="com.action.LoginAction">
			<result name="success">/success.jsp</result>
			<result name="error" type="redirect">/error.jsp</result>
			<result name="checkError">/checkSession.jsp</result>
			<interceptor-ref name="defaultInterceptorStack"></interceptor-ref>
		</action>
     

     (7)  ActionProxy把request请求传递给ActionInvocation

           (8)  ActionInvocation依次调用action和interceptor     

             Interceptor的接口定义没有什么特别的地方,除了init和destory方法以外,intercept方法是实现整个拦截器机制的核心方法。而它所依赖的参数ActionInvocation则是我们之前章节中曾经提到过的著名的Action调度者。

我在这里需要指出的是一个很重要的方法invocation.invoke()。这是ActionInvocation中的方法,而ActionInvocation是Action调度者,所以这个方法具备以下2层含义(详细看DefaultActionInvocation源代码): 
             1. 如果拦截器堆栈中还有其他的Interceptor,那么invocation.invoke()将调用堆栈中下一个Interceptor的执行。 

             2. 如果拦截器堆栈中只有Action了,那么invocation.invoke()将调用Action执行。

     3.

     

      这是我的interceptor类:

       

/**
 * 
 */
package com.interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;

/**
 * @author dandan
 *
 */
public class MyInterceptor implements Interceptor {

	/* (non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#destroy()
	 */
	@Override
	public void destroy() {
		System.out.println("-------destroy()--------");

	}

	/* (non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#init()
	 */
	@Override
	public void init() {
		System.out.println("-------init()--------");

	}

	/* (non-Javadoc)
	 * @see com.opensymphony.xwork2.interceptor.Interceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
	 */
	@Override
	public String intercept(ActionInvocation arg0) throws Exception {
		System.out.println("-------intercept()--------");
		return null;
	}

}
      这是我的配置文件:

      

<interceptors>
			<interceptor name="myInterceptor" class="MyInterceptor"></interceptor>
			<interceptor name="otherMyInterceptor" class="com.interceptor.OtherMyInterceptor"></interceptor>
			<interceptor-stack name="defaultInterceptorStack">
				<!-- <interceptor-ref name="myInterceptor"></interceptor-ref> -->
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>

			<interceptor-stack name="otherMyInterceptor">
				<interceptor-ref name="otherInterceptor"></interceptor-ref>
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="defaultInterceptorStack"></default-interceptor-ref>

     (9)  根据action的配置信息,产生result

           (10) Result信息返回给ActionInvocation

           (11) 产生一个HttpServletResponse响应

           (12) 产生的响应行为发送给客服端。

      struts1与struts2对比

      在Action实现类方面:
      Struts1要求Action类继承一个抽象基类;Struts1的一个具体问题是使用抽象类编程 而不是接口。

      Struts2 Action类可以实现一个Action接口,也可以实现其他接口,使可选和定制服务成为可能。Struts2 提供一个ActionSupport基类 去实现常用的接口。

      线程模式方面:
       Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能做的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的;

       Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。 

      Servlet依赖方面:
      Struts1 Action依赖于Servlet API,因为Struts1 Action的execute方法中有HttpServletRequest和HttpServletResponse方法。
      Struts2 Action 不再依赖于ServletAPI,从而允许Action脱离Web容器运行,从而降低了测试Action的难度。当然,如果Action 需要直接访问HttpServletRequest和HttpServletResponse参数,Struts2 Action仍然可以访问它们。但是,大部分时候,Action都无需直接访问 HttpServletRequest和HttpServletResponse,从而给开发者更多灵活的选择。 

      封装请求参数方面:
      Struts1 使用ActionForm对象封装用户的请求参数,所有的ActionForm 必须继承一个基类:ActionForm。因此,开发者必须创建大量的ActionForm类封装用户请求参数。

      Struts2 直接使用Action 属性来封装用户请求属性,避免了开发者需要大量开发ActionForm类的繁琐,Struts 2 提供了ModelDriven 模式,可以让开发者使用单独的Model 对象来封装用户请求参数,但该Model对象无须继承任何Struts2基类,是一个POJO,从而 降低了代码污染。

      表达式语言方面:
      Struts1 整合了JSTL,因此可以使用JSTL表达式语言。这种表达式语言有基本对象图遍 历,但在对集合和索引属性的支持上则功能不强
      Struts2 可以是用JSTL,但它整合了一种更强大和灵活的表达式语言:OGNL(Object Graph Notation Language),因此,Struts2下的表达式语言功能更加强大。

相关文章
|
安全 Java API
Struts2
访问web资源 1》使用servlet API解耦的方式,获取的方法较少   1.使用ActionContext,一个一个获取,效率不高   2.实现XxxAware接口(ApplicationAware,SessionAware.....)推荐,
45 0
|
设计模式 开发框架 安全
Struts,你为何死不悔改!
上篇文章《诡异的字符串问题。。。》的问题已经解决了,我一直相信「团队力量的重要性」,虽然我不能保证加入群的每一个人都是乐于分享的同学,但我始终群里的各位同学总会慢慢被我们这种乐于分享的群氛围所影响。就以上篇文章为例,群里的 Univechige 同学专门给 IntelliJ IDEA 官方发邮件寻求原因,这便是一个好的开端,我相信有各位同学的共同维护,后面群氛围会越来越好。下面给出 IDEA 官方的答复,见下图。
184 0
Struts,你为何死不悔改!
|
Web App开发 Java Apache
struts
运行流程 客户端浏览器通过HTTP请求,访问控制器,然后控制器读取配置文件,然后执行服务器端跳转,执行相应的业务逻辑,然后,在调用模型层,取得的结果展示给jsp页面,最后返回给客户端浏览器 组成部分 struts 视图 标签库 控制器 action 模型层 ActionFrom JavaBean struts maven 安装官网 : https://struts.
1014 0
|
XML 安全 Java
day25_day27_Struts2_学习回顾
day25_01_学习回顾    1、Struts2框架在三层架构中哪部分进行的再优化?    答:         表现层、MVC模式。2、Struts1和Struts2的一个显著区别是什么?    答:         Struts1的核心控制器是一个servlet。
1485 0
|
Web App开发 XML Java
JakartaEE Struts2使用
1. Struts2下载 解压后的目录结构如下: 图1.png 从一个高水平角度看,Struts2 是一个MVC拉动的(或MVC2)框架,Struts2 的模型-视图-控制器模式是通过以下五个核心部分进行实现的: 操作(Actions...
1034 0
|
Java 数据库连接
[Struts]HibernatePlugIn for Struts(转贴)
这个Plugin的作用是在Struts应用程序启动时进行hibernate的初始化操作,原文HibernatePlugIn for Struts,步骤很简单: 1、在struts-config.xml里增加: <plug-in className="org.
1173 0
|
SQL JavaScript 前端开发
|
Java 数据安全/隐私保护 开发者