文章标题

Struts2——–学习总结
先来介绍一下什么是Struts2:
Struts是一个基于MVC设计模式的WEB应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并的全新的Struts2的体系结构差别巨大。Struts2以WebWork为核心,采用拦截器的机制来处理用户请求,这样的设计也使得业务逻辑控制器能够与servletAPI完全脱离开,所以Struts2可以理解为WebWork的个更新产品。虽然从Struts1到Struts2有着太大的变化,但是相对于WebWork,Struts2的变化很小。
Struts2的下载:
http://struts.apache.org/download.cgi
Struts-2.3.16.3-all.zip
解压后的文件:

Lib是struts2里面所有需要使用的jar包
Docs是一些文档手册
Src里面是源代码
Apps 里面的war文件:

这里只介绍三个常用的war包
Struts2-blank.war :空白项目包里面有常用的jar及xml配置文件
Struts2-showcase.war :里面有很多小案例可以参考。
Struts2-portlet.war : 里面有门户网站的实例代码可供参考

准备环境:

拷贝好jar包之后再找到web.xml 和struts.xml拷贝到项目的src目录下进行修改配置。
Struts.xml的配置:
可以在Web App Libraries 下面找到struts2-core-2.3.16.3.jar-struts-default.xml 里面定义了一些struts.xml常用的常量。
… … .

this—表示集合是的元素

: 从actioncontext中取值,前面加上#。相当于:ActionContext.getContext()。

%: %{#username}百分号的作用就是将大括号中的值当成ognl表达式。测试代码如下:
<%@ page language=”java” import=”java.util.*” pageEncoding=”gbk”%>
<%@ taglib prefix=”s” uri=”/struts-tags”%>
<%
request.setAttribute(“a”,”aaa”);
%>
<s:form>
<s:textfield value="#request.a" label="getText('country')"></s:textfield>
<s:textfield value="%{#request.a}" label="%{getText('country')}" ></s:textfield>
</s:form>

执行上面代码,显示效果如下:

什么是拦截器、拦截器栈?
Interceptor拦截器类似于我们前面学过的过滤器,是可以在action执行前后执行的代码。是我们做web开发时经常用的技术。比如:权限控制、日志等。我们也可以将多个Interceptor连在一起组成Interceptor栈。

Struts2拦截器,每个拦截器类只有一个对象实例,即采用单例模式,所有引用这个拦截器的Action都共享这一拦截器类的实例,因此,在拦截器中如果使用类变量,要注意同步问题。

• 拦截器是在访问某个方法,字段之前或之后实施拦截。
• 拦截器是AOP的一种实现
• 拦截器栈(Interceptor Stack)
– 拦截器栈就是将拦截器按一定的顺序联结成一条链。
– 在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
• 实现原理
– Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对应拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。
拦截器和过滤器的区别
1. 拦截器和过滤器的概念非常类似
2. 过滤器是web中的概念,可以过滤一切对象(包括action、servlet、jsp、html等等)。
3. 而拦截器是struts2中的概念,只能拦截action(无法拦截对jsp的请求)。
4. 过滤器内部采用函数回调来实现。拦截器采用动态代理来实现!
Struts2拦截器示意图

拦截器在struts2中的应用
• 对于Struts2框架而言,正是大量的内置拦截器完成了大部分操作。比如:
– 像params拦截器将http请求中参数解析出来赋值给Action中对应的属性。
– Servlet-config拦截器负责把请求中HttpServletRequest实例和HttpServletResponse实例传递给Action
– …
• struts-default.xml中有一个默认的引用,在默认情况下(也就是中未引用拦截器时)会自动引用一些拦截器。
默认拦截器说明
• alias:对于HTTP请求包含的参数设置别名。
• autowiring:将某些JavaBean实例自动绑定到其他Bean对应的属性中。有点类似Spring的自动绑定,在Spring部分会详细说明。
• chain:在Web项目开发中,以前使用Struts开发时候经常碰到两个Action互相传递参数或属性的情况。该拦截器就是让前一Action的参数可以在现有Action中使用。
• conversionError:从ActionContext中将转化类型时候发生的错误添加到Action的值域错误中,在校验时候经常被使用到来显示类型转化错误的信息。
• cookie:从Struts2.0.7版本开始,可以把cookie注入Action中可设置的名字或值中。
• createSession:自动创建一个HTTP的Session,尤其是对需要HTTP的Session的拦截器特别有用。比如下面介绍的TokenInterceptor。
• debugging:用来对在视图间传递的数据进行调试。
• execAndWait:不显式执行Action,在视图上显示给用户的是一个正在等待的页面,但是Action其实是在“背后”正在执行着。该拦截器尤其在对进度条进行开发的时候特别有用。
• exception:将异常和Action返回的result相映射。
• fileUpload:支持文件上传功能的拦截器。
• i18n:支持国际化的拦截器。
• logger:拥有日志功能的拦截器。
• modelDriven:Action执行该拦截器时候,可以将getModel方法得到的result值放入值栈中。
• scopedModelDriven:执行该拦截器时候,它可以从一个scope范围检索和存储model值,通过调用setModel方法去设置model值。
• params:将HTTP请求中包含的参数值设置到Action中。
• prepare:假如Action继承了Preparable接口,则会调用prepare方法。
• staticParams:对于在struts.xml文件中Action中设置的参数设置到对应的Action中。
• scope:在session或者application范围中设置Action的状态。
• servletConfig:该拦截器提供访问包含HttpServletResquest和HttpServletResponse对象的Map的方法。
• timer:输出Action的执行时间。
• token:避免重复提交的校验拦截器。
• tokenSession:和token拦截器类似,但它还能存储提交的数据到session里。
• validation:运行在action-validation.xml(校验章节介绍)文件中定义的校验规则。
• workflow:在Action中调用validate校验方法。如果Action有错误则返回到input视图。
• store:执行校验功能时候,该拦截器提供存储和检索Action的所有错误和正确信息的功能。
• checkbox:视图中如果有checkbox存在的情况,该拦截器自动将unchecked的checkbox当作一个参数(通常值为“false”)记录下来。这样可以用一个隐藏的表单值来记录所有未提交的checkbox,而且缺省unchecked的checkbox值是布尔类型的,如果视图中checkbox的值设置的不是布尔类型,它就会被覆盖成布尔类型的值。
• profiling:通过参数来激活或不激活分析检测功能,前提是Web项目是在开发模式下。(涉及到调试和性能检验时使用)
• roles:进行权限配置的拦截器,如果登录用户拥有相应权限才去执行某一特定Action。

计时拦截器
timer拦截器能够统计每个action的执行时间。原理很简单:就是在执行action前纪录一个时间,执行action后纪录一个时间。两个时间纪录相减即可获得action的执行时间。
timer拦截器使用方式非常简单:在action的配置中增加timer拦截器配置即可:
<package name="test" namespace="/" extends="struts-default">
<action name="testValidate" class="com.bjsxt.struts.test.TestValidateAction">
<interceptor-ref name="timer"></interceptor-ref>
<result name="success">/ok.jsp</result>
<result name="input">/testFormLabel.jsp</result>
</action>
</package>

这样我们访问相应的action,控制台就会打印:
2011-5-5 14:03:42 com.opensymphony.xwork2.util.logging.jdk.JdkLogger info
信息: Executed action [//testValidate!execute] took 78 ms.

注:使用默认拦截器,我们的元素必须要有:extends=”struts-default”
token防止表单重复提交拦截器
表单重复提交,是我们在写系统时一定要避免的!尤其是在购物、银行等系统中。通过令牌机制防止表单的重复提交(我们在中级项目中已经做过!)。
在struts2中,我们可以通过token拦截器轻松实现防止表单重复提交功能!
1. 在相应的action配置中增加:

<package name="test" namespace="/" extends="struts-default">
<action name="testValidate" class="com.bjsxt.struts.test.TestValidateAction">
<interceptor-ref name="token"></interceptor-ref>
<result name="success">/ok.jsp</result>
<result name="input">/testFormLabel.jsp</result>
<result name="invalid.token">/tokenInvalid.jsp</result>
</action>
</package>

  1. 增加tokenInvalid.jsp文件,代码如下:
    <%@ page language=”java” import=”java.util.*” pageEncoding=”gbk”%>

表单不能重复提交!!

  1. 在所提交的表单上增加:标记。

<s:form action="testValidate" >
<s:textfield name="uname" ></s:textfield>
<s:token></s:token>
<s:submit></s:submit>
</s:form>

测试:

提交表单到相应的action,点击提交按钮后,顺利提交。地址栏变为:
http://localhost:8080/teststruts/testValidate

直接点击刷新按钮,刷新地址栏后,跳转到tokenInvalid.jsp:

自定义拦截器
• 直接或间接实现接口com.opensymphony.xwork2.interceptor.Interceptor
• 或者继承类com.opensymphony.xwork2.interceptor.AbstractInterceptor
• 通过元素来定义拦截器
• 通过元素来使用拦截器
• 重写public String intercept(ActionInvocation ai) throws Exception
• 注意:
– 如果为Action指定了一个拦截器,则系统默认的拦截器栈将会失去作用。为了继续使用默认拦截器,所以上面配置文件中手动引入了默认拦截器
• 取得Action对象,从而取得对Action的完全控制
TestAction testaction = (TestAction) ai.getAction();
System.out.println(“action中的属性id:”+testaction.getId());

• 继续执行action,执行后对响应的处理
ai.invoke();
System.out.println(“执行完action后,action中的属性id:”+testaction.getId());

• 取得ActionContext对象(存放Action执行时需要用到的对象),将Servlet相关数据转换为与ServletAPI无关的Map对象(即ActionContext)
ActionContext ac = ai.getInvocationContext();
System.out.println(ac.getSession().get(“a”)); //得到HttpSession的Map对象
Map requestmap = (Map) ac.get(“request”); //得到HttpServletRequest的Map对象
System.out.println(“—–”+requestmap.get(“id”));
Map applicationMap=ac.getApplication(); //得到ServletContext的Map对象

• 获得servlet中相关对象
HttpServletRequest req = ServletActionContext.getRequest();
ServletActionContext.getResponse();
ServletActionContext.getServletContext();
ServletActionContext.getRequest().getSession();

拦截器执行顺序
• 根据拦截器执行情况:
– 拦截方法之前执行:配置在前面的拦截器,先执行。
– 拦截方法之前执行:配置在前面的拦截器,后执行。

方法拦截器
• Struts2提供MethodFilterInterceptor类,该类是AbstractInerceptor的子类,可以实现对Action方法的拦截.
• 重写:doIntercept方法
• MethodFilterInterceptor中参数配置:
– 如果一个方法同时在excludeMethods和includeMethods中出现,则会被拦截
– 如果不配置这两个参数,所在action所有方法都会拦截

<interceptor name="testmethod" class="com.cssxt.interceptor.TestMethodInterceptor">
<param name="includeMethods">add,add2</param>
<param name="excludeMethods">add3,add4</param>
</interceptor>

文件上传
struts2为我们提供了简便的上传支持,内部仍然使用了apache commons fileupload组件。我们只需要按照如下步骤操作,即可轻松完成文件上传操作:
1. action代码如下:
`package com.bjsxt.gao;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import com.opensymphony.xwork2.ActionSupport;

public class Upload2Action extends ActionSupport {
private String title;

private File upload;  //封装上传文件域
private String uploadContentType; //封装上传文件类型
private String uploadFileName; //封装上传文件名

private String savePath;

//get和set方法,省略!

public String execute() throws Exception{
    System.out.println(uploadFileName);
    System.out.println(uploadContentType);
    FileOutputStream fos = new FileOutputStream(getSavePath()+getUploadFileName());
    FileInputStream fis = new FileInputStream(getUpload());
    byte[] buf = new byte[1024];
    int len = 0;
    while((len = fis.read(buf))>0){
        fos.write(buf, 0, len);
    }

    fos.close();
    fis.close();

    return SUCCESS;

}

}`

  1. 配置action:

<action name="Upload" class="com.bjsxt.gao.Upload2Action">
<param name="savePath">d:/temp/</param> <!-- 可以通过这种方式在配置文件中设置action属性的值 -->
<result name="input">/index.jsp</result>
<result name="error">/error.jsp</result>
<result name="success">/ok.jsp</result>
</action>

  1. jsp页面如下:

    <form action="Upload.action" enctype="multipart/form-data" method=post >
    文件标题:<input type=text name=title /> <br/>
    选择文件:<input type=file name=upload /><br/>
    <input type=submit value=上传 />
    </form>

通过上面的步骤。我们可以发现struts2中的上传处理。所上传的文件很直观的封装到对应的File对象中。

自学:
1. 如何上传多个文件!(提示:File数组即可实现)
2. 增加文件类型、上传文件最大大小的限制验证!
3. struts2上传进度条的实现
拦截器栈
定义拦截器栈:
<interceptor-stack name="stack1">
<interceptor-ref name="timer"></interceptor-ref>
<interceptor-ref name="my2"></interceptor-ref>
</interceptor-stack>

直接在action中引用即可:
<action name="test3" class="com.bjsxt.test.Test3Action">
<interceptor-ref name="stack1"></interceptor-ref>
<result name="success">/ok.jsp</result>
</action>

默认拦截器(栈)
1. 默认拦截器只针对中没有手动配置拦截器的action有效!
2. 包中定义的默认拦截器生效,则struts-default包中定义的默认拦截器失效。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值