您的位置:首页 > 编程语言 > Java开发

struts1与struts2的对比学习

2015-09-27 08:37 363 查看
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下的表达式语言功能更加强大。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: