Struts2拦截器的使用
struts2中如何拦截刷新造成数据重复写入论文
struts2中如何拦截刷新造成的数据重复写入【摘要】在现在web开发中,struts+spring+hinernate的模式运用得非常广泛,但在使用struts2通过jsp页面提交数据时或用户在提交数据后再次刷新提交页面会造成数据的重复提交,这样会在数据库中生成重复的数据或者引起数据库的数据异常。
本文通过实例详细介绍了在struts2中如何拦截刷新造成的数据重复写入的问题。
【关键词】拦截;刷新;重复;数据库;写入1.问题提出在struts2中通常的处理时将jsp作界面,action作数据处理。
例如一个添加新记录的处理,先写一个界面deptappend.jsp,代码如下:添加系部再写一个action用来进行数据处理,代码如下:public class deptappend extends actionsupport{ private deptdao deptdao;private string deptname;public deptdao getdeptdao() {return deptdao;}public void setdeptdao(deptdao deptdao) { this.deptdao = deptdao;}public string getdeptname() {return deptname;}public void setdeptname(string deptname) { this.deptname = deptname;}@overridepublic string execute() throws exception {// todo auto-generated method stubdept dept=new dept();dept.setdeptname(deptname);deptdao.save(dept);list list=deptdao.findall();actioncontext context=actioncontext.getcontext();context.put(“deptlist”, list);return success;}}最后在struts.xml中加入此action中的配置就行了/dept.jsp此处还使用了spring,所以还应在applcationcontext.xml中加入此action的bean接下来发布,打开页面可以添加数据了。
基于AOP理念的Struts2拦截器的研究与应用
中图 分 类 号 : P l T3】
文 献标 识 码 : A
文 章编 号 : 6 4 6 3 ( 0 0 0 一 0 8 0 17 — 26 2 1 ) l0 0 — 2
Re e r h a pp i a i n o r t 2 i t r e t r b s d o o o fAO P s a c nd a lc to fSt u s n e c p o a e n l g s o
安 全 验 证 、 日志 等 功 能往 往水 平 散 布 在 所 有 对 象 层 次 中 , 而
与 其 所 散 布 到 的 对象 核心 功能 没有 关 系 。这些 散 布 在各 处 的 代 码 被 称 为 横 切 代 码 , O P设 计 中 , 们 造 成 大 量 代 码 的 在 O 它 重 复 , 利 于各 个 模 块 的 复 用 。而 A P则 可 以 减 少 系统 中 的 不 O
n e e a d fe i lt fit r e t n s l i h r blm s ine n xbii o n e c pori o vngt e p o e . l y
Ke r s s e tO ine Po rmmig AOP) cos ut gc n en s a ;nec po y wo d :A p c— re td rga n( ; rsc tn o c r; w p itre tr i
增 多 和应 用 范 的扩 大 , 渐 暴 露 其 不 足和 局 限性 . 逐 . 比如一 个 系统 中有 几 十 个 或 几 百 个 数据 库 查 询 函数 .每 个 地 方 都 要
O P不 能 为 分 散 的对 象 引 入 公 共 行 为 。也 就 是 O P允许 定 O O
义 从 上 到 下 的关 系 , 并 不 适 合 定 义 从 左 到 的 关 系 。例 如 但
用拦截器实现访问权限控制
Struts自定义拦截器步骤(教材P100)
步骤1:建立Struts工程,编写Action和相应的页面 步骤2:自定义一个实现Interceptor接口的类,在
intercept方法中实现拦截器逻辑 步骤3:在struts.xml中为指定Action位置添加拦截
</boLeabharlann y>学习情境2 Struts2拦截器应用举例
步骤4:编写拦截器控制权限
拦截器取出Session中存入的状态码,判断用户身份
ActionContext ctx = invocation.getInvocationContext(); Map session = ctx.getSession(); String user = (String) session.get("username"); If(user!=null&&user.equals(“admin”)) return "admin";//进入管理页面 else{ ctx.put(“tip”, “您没有管理员的权限!”); //可用EL表达式语言取出 return “input”; //返回到登录页面 }
学习情境2 Struts2拦截器应用举例
步骤1:建立Struts工程,编写LoginAction和相应 的登录页面
在LoginAction中,若登录成功,在Session中写入 身份标志信息。
If(用户名密码正确) { ActionContext ctx = ActionContext.getContext(); Map session = ctx.getSession(); session.put("username" , getUsername());
struts2拦截器--将用户操作日志存入数据库
struts2拦截器--将用户操作日志存入数据库第一篇:struts2拦截器--将用户操作日志存入数据库struts2拦截器--将用户操作日志存入数据库1.建表,如下所示:2.新建OperationLogModel.java,其具有上述属性。
3.自动生成PO4.在struts.xml中配置拦截器:5.如下例子中的用户登录和修改密码,要在相应xml文件中加入,即:indexchangePasswordPre6.在项目中新建文件夹log,在其下新建类LogInterceptor .java,如下:package com.bfw.crms.log; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import ng.StringUtils; import org.apache.log4j.Logger; import org.apache.struts2.ServletActionContext; import com.bfw.crms.action.BulletinAction; import com.bfw.crms.action.SystemAction; import com.bfw.crms.model.EmployeeModel; import com.bfw.crms.model.OperationLogModel; import com.bfw.crms.po.OperationLog; import com.bfw.crms.util.BeanUtil; import com.bfw.crms.util.DateTimeUtil; import com.ninetowns.framework.dao.ObjectDao; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;@SuppressWarnings("serial")public class LogInterceptor extends AbstractInterceptor{ private String logName;private String logContent;protected Logger log = Logger.getLogger(getClass()); protected HttpSession getSession(){return getRequest().getSession();}protected HttpServletRequest getRequest(){return ServletActionContext.getRequest();}public void init() {}private ObjectDao objectDao = null;public ObjectDao getObjectDao(){return objectDao;}public void setObjectDao(ObjectDao objectDao){this.objectDao = objectDao;}@Overridepublic String intercept(ActionInvocation ai) throws Exception {Object action= ai.getAction();String method= ai.getProxy().getMethod();try{if(StringUtils.isBlank(method)) method = "method";EmployeeModel sysUser (EmployeeModel)this.getSession().getAttribute("employee");String userName = "";if(sysUser!=null) userName = sysUser.getName();=String currentTime = DateTimeUtil.getDateTime();String logContentHead = "用户"+userName+currentTime;ai.invoke();//执行被拦截actionif (action instanceof BulletinAction) {if(method.equals("save")){logName = "保存部门";logContent = logContentHead+"保存部门:"+ai.getStack().findValue("Name");(logContent);addSysLog(logName,logContent);}if(method.equals("delete")){logName = "删除部门";logContent = logContentHead +""+((String[])(ai.getStack().findValue("flag_id"))).length+"条部门信息";(logContent);addSysLog(logName,logContent);}}if (actioninstanceof SystemAction) {if(method.equals("login")){logName = "登录系统";logContent = logContentHead;(logContent);addSysLog(logName,logContent);}if(method.equals("changePassword")){logName = "修改密码";logContent = logContentHead +"删除1条单位信息";(logContent);addSysLog(logName,logContent);}}}catch(Exception e){e.printStackTrace();}return Action.SUCCESS;}/*** 插入系统日志 model2po()* @param logName* @param logContent*/删除private void addSysLog(String logName,String logContent){ OperationLogModel operationModel = new OperationLogModel();OperationLog operationPO = new OperationLog();operationModel.setOperation(logContent);BeanUtil.model2po(operationModel, operationPO);this.getObjectDao().saveObject(operationPO);}} OK第二篇:Struts2中的拦截器与过滤器学习拦截器是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法,比如动态代理就是拦截器的简单实现,过滤器是在java web中,你传入的request,response 提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do 的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符。
02-Struts2的工作流程及配置文件
Struts2的工作流程及配置文件--- ---Struts2.0的流程图从图中看到Struts2的工作流程如下:1.服务器接收到的请求首先经过一组过滤器链(实际中的其他过滤器可能还包括诸如Spring 的字符过滤器CharactorEncodingFilter、V elocity的过滤器等,一般FilterDispatcher位于过滤器的最后一个执行),过滤器链按照你在web.xml中的配置顺序在接收客户请求时顺序执行,在向客户发送响应时反序执行,Struts2的核心FilterDispatcher在web.xml中的配置如下:<filter><filter-name>setCharactor</filter-name><!-- 配置字符过滤--><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class><init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param></filter><filter><filter-name>struts2</filter-name><!-- 配置Struts2过滤器--><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> </filter><filter-mapping><filter-name>setCharactor</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>注意:如果你使用的是W ebLogic6.1作为应用服务器,需要使用FilterDispatcherCompatW eblogic61替代FilterDispatcher。
paginationinnerinterceptor使用
paginationinnerinterceptor使用分页是在网站开发中非常常见的功能之一,可以帮助用户更方便地查看和导航大量的数据。
为了实现分页功能,我们通常会使用一些第三方的库或者插件,来简化开发过程。
而在Java开发中,Struts2框架提供了一个名为paginationinnerinterceptor的拦截器,可以很方便地实现分页功能。
paginationinnerinterceptor是Struts2框架中的一个拦截器,它的作用是拦截Action请求,并对分页参数进行处理。
使用paginationinnerinterceptor可以将分页参数直接映射到Action的属性上,从而实现分页功能。
下面我们来看一下如何使用paginationinnerinterceptor来实现分页功能。
首先,我们需要在Struts2的配置文件struts.xml中配置paginationinnerinterceptor。
我们可以定义一个全局的拦截器栈,在拦截器栈中添加paginationinnerinterceptor拦截器。
具体的配置如下所示:```xml<package name="default" namespace="/" extends="struts-default"><interceptors><interceptor-stack name="paginationStack"><interceptor-ref name="defaultStack" /><interceptor-ref name="paginationinnerinterceptor" /></interceptor-stack></interceptors><default-interceptor-ref name="paginationStack" />...</package>```接下来,我们需要在Action中定义用于接收分页参数的属性。
struts2常见面试题
struts2常见面试题Introduction:Struts2是一种用于开发Java Web应用程序的开源Web应用框架。
在软件工程领域,Struts2常常是面试中的热门话题。
本文将介绍一些常见的Struts2面试题,并提供详细解答和示例。
Question 1: 什么是Struts2框架?它的主要特点是什么?Struts2是一个基于MVC设计模式的Web应用框架。
它通过集成多个核心组件(如拦截器、过滤器、表单验证等)提供了一套丰富的功能,用于简化开发和管理Java Web应用程序。
Struts2的主要特点包括:1. 松耦合:Struts2使用基于配置的方式来管理组件之间的依赖关系,降低了模块之间的耦合。
2. 灵活性:开发人员可以根据自己的需求进行扩展和定制,以适应不同的项目需求。
3. 可测试性:Struts2的组件松耦合特点使得单元测试变得容易,并且可以方便地模拟用户请求进行测试。
Question 2: Struts2的核心组件有哪些?Struts2的核心组件包括:1. Action:处理用户请求的核心组件,负责接收请求并执行相应的业务逻辑。
2. Interceptor:用于对请求进行预处理和后处理的拦截器组件。
3. Result:负责生成响应结果,可以是页面视图或其他格式的数据(如JSON、XML等)。
4. FilterDispatcher:负责将请求分发给合适的Action处理。
5. ValueStack:用于存储Action处理的结果数据,支持OGNL表达式以便于数据的访问和操作。
Question 3: 如何定义一个Struts2的Action?在Struts2中,可以通过以下几种方式来定义一个Action:1. 实现Action接口:通过实现Action接口,并提供相应的业务方法来处理请求。
2. 继承ActionSupport类:ActionSupport是一个提供了一些方便方法的抽象类,可以直接继承并实现自己的业务逻辑。
struts2 error处理
struts2 error处理Struts2错误处理可以通过以下几种方式进行处理:1. 全局异常处理器(Global Exception Handler):可以通过实现`com.opensymphony.xwork2.Action`接口,并定义`execute()`方法来处理所有的异常。
在struts.xml配置文件中添加如下内容:```xml<global-exception-mappings><exception-mapping exception="ng.Exception"result="error" /></global-exception-mappings>```2. Action级别的异常处理器:每个Action类可以通过实现`com.opensymphony.xwork2.Action`接口,并定义`execute()`方法来处理特定的异常。
在struts.xml配置文件中,为每个使用自定义处理器的Action配置异常处理器:```xml<action name="example" class="com.example.ExampleAction"> <exception-mapping exception="ng.Exception"result="error" /><result name="error">/error.jsp</result><result>/example.jsp</result></action>```3. 拦截器异常处理器:Struts2中的拦截器可以捕获并处理Action方法中的异常。
可以通过自定义拦截器来实现异常处理,然后在struts.xml配置文件中使用:```xml<action name="example" class="com.example.ExampleAction"><interceptor-ref name="exceptionInterceptor" /><result>/example.jsp</result></action>```以上是Struts2错误处理的几种典型方法,可以根据具体需求选择适合的方式进行处理。
Struts2的拦截器配置
拦截器实例
public class SimpleInterceptor extends AbstractInterceptor { private String name; public void setName(String name) { = name; } public String intercept(ActionInvocation invocation) throws Exception { LoginAction action = (LoginAction)invocation.getAction(); ......... String result = invocation.invoke(); ...... return result; } }
Struts 专题篇
第九章 Struts 2 的拦截器 主讲:陈宝峰
内容描述
● ● ● ● ● ●
拦截器概述 拦截器配置 使用拦截器的配置 使用默认拦截器的配置 拦截器实例 方法过滤
拦截器概述
● ●
拦截器是 Struts 2 中的重要组成部分 大量的内建拦截器完成了大部分的 Struts2 框架的工作
结束
使用默认拦截器的配置
<package name=” 包名” > <interceptors> <interceptor name=” 拦截器名 1” class=”......” /> ...... <interceptor-stack name=” 拦截器栈名 1”> <interceptor-ref name=” 拦截器名 1” /> ...... </interceptor-stack> </interceptors> <default-interceptor-ref name=” 拦截器名或拦截器栈名” /> <action ...... /> </package>
拦截器
ConfigurationProvider&Configuration ConfigurationProvider就是Struts2中配置文件的解析器,Struts2中的配置文件主 要是尤其实现类 XmlConfigurationProvider及其子类StrutsXmlConfigurationProvider 来解析。
拦截器就是AOP(AspectOriented Programming)的 一种实现。(AOP是指用于 在某个方法或字段被访问之 前,进行拦截然后在之前或 之后加入某些操作(与业务逻 辑无关的操作:文件上传, 防止表单重复提交,日 志。。)
ActionMapper其实是HttpServletRequest和Action调用请求的一个映射 ActionProxy作用是如何取得Action,ActionInvocation的作用是如何 执行Action,拦截器的功能就是在ActionInvocation中实现的。 ConfigurationProvider就是Struts2中配置文件的解析器
ActionMapper ActionMapper其实是HttpServletRequest和Action调用请求的一个映射,它屏蔽了 Action对于Request等 java Servlet类的依赖。Struts2中它的默认实现类是 DefaultActionMapper,ActionMapper很大的用处可以根据自己的需要来设计url格式, 它自己也有Restful的实现,具体可以参考文档的docs\actionmapper.html。
ActionProxy&ActionInvocation Action的一个代理,由ActionProxyFactory创建,它本身不包括Action实例,默 认实现DefaultActionProxy是由ActionInvocation持有on实例。ActionProxy作用 是如何取得Action,无论是本地还是远程。而 ActionInvocation的作用是如何执行 Action,拦截器的功能就是在ActionInvocation中实现的。
struts2异常拦截处理
struts2异常拦截处理在实际开发中,我们需要将捕获的异常信息打印出来,换上通俗的语言让客户能够大概了解是原因引起的异常,所以我们需要将异常信息显示到页面上来,让客户能够看得见。
这里介绍以下struts2的异常处理机制。
在sturts2的struts-default.xml中,引用了struts2定义的拦截器:<interceptor name="exception" class="com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor"/下面是一个小例子来说明struts2中,应该如何捕获异常信息,并将异常信息显示到页面:一个简单的index.jsp页面,只有一个按钮,点击进入action:<s:form action="login"><s:submit value="submit"/></s:form>struts.xml的配置:<struts><package name="Action" extends="struts-default"><global-results><result name="all">/error.jsp</result></global-results><global-exception-mappings><exception-mapping result="all" exception="ng.Exception"></exception-mapping></global-exception-mappings><action name="login" class="com.action.LoginAction"><result name="success">/success.jsp</result></action></package></struts>Action:public class LoginAction extends ActionSupport {@Overridepublic String execute() throws Exception {try{int i = 9/0;}catch (Exception e) {throw new Exception(e);}return "success";}}打印错误信息的页面 error.jsp:<body><s:property value="exception.message"/></body>这样就可以把异常信息打印到指定的页面,当然也可以在struts.xml中定义局部的异常映射信息。
struts2 multipartrequest用法
struts2 multipartrequest用法Struts2 MultipartRequest 使用方法:Struts2 是一个用于构建 Java Web 应用的开源框架,它提供了许多功能和工具来简化开发过程。
其中之一就是 MultipartRequest,它是用于处理涉及文件上传的请求的。
要使用 Struts2 的 MultipartRequest,首先需要在 Struts2 的配置文件中进行相应的配置。
1. 配置 web.xml 文件:在 web.xml 文件中,将 Struts2 的过滤器配置为请求的第一个过滤器。
```xml<filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter><filter-mapping><filter-name>struts2</filter-name><url-pattern>/*</url-pattern></filter-mapping>```2. 配置 struts.xml 文件:在 struts.xml 文件中,添加对文件上传的支持。
示例如下:```xml<interceptors><!-- 其他拦截器配置 --><interceptor name="fileUpload"class="org.apache.struts2.interceptor.FileUploadInterceptor" /></interceptors><action name="uploadAction" class="com.example.UploadAction"><interceptor-ref name="fileUpload" /><interceptor-ref name="defaultStack" /><result>/success.jsp</result></action>```在上述示例中,我们定义了一个名为 "uploadAction" 的 action,使用了fileUpload 拦截器和 defaultStack 拦截器栈。
java 过滤器、监听器 拦截器 原理个人总结
过滤器创建一个Filter 只需两个步骤:(1)创建Filter 处理类:(2)在web.xml 文件中配置Filter 。
创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。
• void init(FilterConfig config): 用于完成Filter 的初始化。
• void destroy(): 用于Filter 销毁前,完成某些资源的回收。
• void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 实现过滤功能,该方法就是对每个请求及响应增加的额外处理。
过滤器Filter也具有生命周期:init()->doFilter()->destroy(),由部署文件中的filter元素驱动。
在servlet2.4中,过滤器同样可以用于请求分派器,但须在web.xml中声明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>该元素位于filter-mapping中。
一、理解Struts2拦截器1. Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现.2. 拦截器栈(Interceptor Stack)。
Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。
在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。
二、实现Struts2拦截器原理Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器三、定义Struts2拦截器。
Struts2-interceptor
Struts2拦截器一、什么是拦截器?1、拦截器,在AOP(Aspect-Oriented Programming<面向切面编程>)中用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。
拦截是AOP的一种实现策略。
在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。
它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行。
同时也是提供了一种可以提取action 中可重用的部分的方式。
2、拦截器链(Interceptor Chain,在Struts 2中称为拦截器栈Interceptor Stack)。
拦截器链就是将拦截器按一定的顺序联结成一条链。
在访问被拦截的方法或字段时,拦截器链中的拦截器就会按其之前定义的顺序被调用。
3、如何使用struts2拦截器,或者自定义拦截器。
特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器):<interceptor-ref name="checkbox"><param name="uncheckedValue">0</param></interceptor-ref><interceptor-ref name="defaultStack"/>(必须加,否则出错)4、也可以改为对全局Action设置自己需要的拦截器,如下:在struts.xml里面定义全局的配置设置<package name="struts-shop" extends="struts-default"><interceptors><interceptor-stack name="myStack"><interceptor-ref name="checkbox"><param name="uncheckedValue">0</param></interceptor-ref><interceptor-ref name="defaultStack"/></interceptor-stack></interceptors><default-interceptor-ref name="myStack"/>(这句是设置所有Action自动调用的拦截器堆栈)</package>struts-action.xml里面配置Action如下:<package name="LogonAdmin" extends="struts-shop">(这里扩展struts.xml里面定义的配置就可以了)<action name="logon" class="logonAction"><result>/jsp/smeishop/admin/index.jsp</result> <resul t name="error">/jsp/smeishop/admin/logon.jsp</result><result name="input">/jsp/smeishop/admin/logon.jsp</result> </action><action name="logout" class="logoutAction"><result>/jsp/smeishop/admin/logon.jsp</result></action></package>二、Struts2自带的配置及其拦截器配置1、Struts2 拦截器 [Interceptor]拦截器的工作原理如上图,每一个Action请求都包装在一系列的拦截器的内部。
基于struts2拦截器的操作日志系统设计
CA ( ) H
是 台 记 录 操 作 日志 ,0表 不 小 记
_
l g s t r ( u h g t c i n ( ) o .eU l a t. eA to ):
l g. et p o s l
(e veA t oC n et gt eu s ( .eR m tA d ( ) Sr lt c in ot x. eR q et ) gt eo ed r ); d o s v ( o ) a .a e 1g :
摘
40 0 ) 3 2 5
要 :操 作 日志是 各种 应 用 系统非 常重 要 的一部 分 ,它记 录 了用户在 系统 中进行 的操 作 ,为 系统 管理 者进 行 审计跟
踪提 供 了数 据 支撑 。本 文介 绍一种 基 于 sus tt r 2拦截 器模 式 的操作 日志 系统设 计 ,它在 实现 操作 日志记 录的 同时 ,以极其 优 雅及 简洁 的方 式降低 了业务逻 辑 与操 作 日志记 录之 间的耦舍 性 ,是 实现 操作 日志的理 想 选择 。 关键 词 :操 作 日志 系统 ;拦 截 器 ;sus;业务逻 辑 tt r 2
f
(
’
h ^ ) t ^
C
t .1 L
p b s a i a < t i g, y A t a t o > a a : n w u l c t t c M p S r n S s u h c i n i Mp e
p v e t ti A h Aut a i n ut = n 0 ri at s a c ut h ct o a h ul n 1:
SP 0 D V RH R (0 U 1R I A C A 2 2 )
struts核心过滤器FilterDispatcher介绍
struts核心过滤器FilterDispatcher介绍FilterDispatcher功能介绍FilterDispatcher是struts2的核心控制类负责处理最初的请求分发.四大责任1.执行action2.清空ActionContext上下文3.服务静态的内容(初始化环境等)4.中断请求生命周期中的XWORKS拦截器.FilterDispatcher必须映射所有的请求,除非你只想在某一部分支持struts2的功能.配置filter的url-pattern的时候请使用"/*";1.执行action过滤器根据请求的url判断是否需要调用action(判断的依据是根据actionMapper)如果需要执行action那么处于过滤器链中的其他过滤器将终止,并且调用action.这意味着其他一些一定要执行的过滤器必须放在FilterDispatcher前面.以保证他们的执行.2.清空ActionContext上下文FilterDispatcher讲自动的清除上下文,确保没有内存泄露.但是有时候将导致在集成其他产品时出现某些问题.详情,请看ActionContextUp类3.服务静态的内容FilterDispatcher同时会加载常用的静态内容,例如javascript文件,css文件. FilterDispatcher会查找/struts/*这个目录,并且映射"/struts/"后面的的所有常用的包.以下是默认搜索的包org.apache.struts2.statictemplate例如用户可以通过请求/struts/xhtml/styles.css得到struts2的内置的XHTML UI 主题包下面的默认样式表用户还可以通过为filterDispatcher添加packages参数来添加用户自己的包. FilterDispatcher支持以下初始化参数参数名config 参数值以逗号隔开的配置文件名的列表参数名actionPackages 参数值以逗号隔开的java包名,主要用来扫描检测action参数名configProviders 参数值以逗号隔开的配置提供程序的类名.其他的参数名将被当作是框架的常量.public class FilterDispatcher implementsorg.apache.struts2.StrutsStatics,javax.servlet.Filterorg.apache.struts2.StrutsStatics定义了以下常量这些常量用来获取或者设置请求上下文的对象例如通过ActionContext对象和HTTP_REQUEST我们可以获取或者设置HttpServletRequest对象ActionContext.getContext().put(HTTP_REQUEST,request);HttpServletRequest request=(HttpServletRequest)ActionContext.getContext().get(HTTP_REQUEST);public interface StrutsStatics{public static final String HTTP_REQUEST ="com.opensymphony.xwork2.dispatcher.HttpServletRequest";public static final String HTTP_RESPONSE ="com.opensymphony.xwork2.dispatcher.HttpServletResponse";public static final String SERVLET_DISPATCHER ="com.opensymphony.xwork2.dispatcher.ServletDispatcher";public static final String SERVLET_CONTEXT ="com.opensymphony.xwork2.dispatcher.ServletContext";public static final String PAGE_CONTEXT ="com.opensymphony.xwork2.dispatcher.PageContext";public static final String STRUTS_PORTLET_CONTEXT = "struts.portlet.context"; }import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import .URLDecoder;import java.util.ArrayList;import java.util.Calendar;import java.util.Enumeration;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.StringT okenizer;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import mons.logging.Log;import mons.logging.LogFactory;import org.apache.struts2.RequestUtils;import org.apache.struts2.StrutsConstants;import org.apache.struts2.StrutsStatics;import org.apache.struts2.dispatcher.mapper.ActionMapper;import org.apache.struts2.dispatcher.mapper.ActionMapping;import com.opensymphony.xwork2.inject.Inject;import com.opensymphony.xwork2.util.ClassLoaderUtil;import com.opensymphony.xwork2.util.profiling.UtilTimerStack;import com.opensymphony.xwork2.ActionContext;public class FilterDispatcher implementsorg.apache.struts2.StrutsStatics,javax.servlet.Filter{//日志类private static final Log LOG = LogFactory.getLog(FilterDispatcher.class);//路径前缀private String[] pathPrefixes;//为缓存静态内容时设置响应头信息提供日期格式化.private final Calendar lastModifiedCal = Calendar.getInstance();//存储StrutConstants.STRUTS_SERVE_STATIC_CONTENT 的设置,该设置可以通过配置文件设置private static boolean serveStatic;//存储StrutConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE的设置,该设置可以通过配置文件设置.private static boolean serveStaticBrowserCache;//存储字符编码的字符串,该设置可以通过配置文件设置private static String encoding;//通过注入方式提供,ActionMapper的实例private static ActionMapper actionMapper;//FilterConfig过滤器配置类的实例,在init方法中初始化private FilterConfig filterConfig;//为子类暴露Dispatcher对象protected Dispatcher dispatcher;/**初始化过滤器的方法,该方法中创建了一个默认的dispatcher,并且在此方法中设置了静态资源的默认包*/public void init(FilterConfig filterConfig)throws ServletException{this.filterConfig = filterConfig;dispatcher = createDispatcher(filterConfig);dispatcher.init();String param = fitlerConfig.getInitParamter("pagckages");String packages = "org.apache.struts2.static templateorg.apache.struts2.interceptor.debugging";if(param != null){packages = param + " "+packages;}this.pathPrefixes = parse(packages);}/**当应用被终止时调用destroy方法,该方法用来用来释放本地线程和任何的DispatcherListeners**/public void destroy(){if(dispatcher==null){LOG.warn("something is seriously wrong,Dispatcher is not initialized(null)");}else{dispatcher.cleanup();}}/**创建默认的Dispatcher对象.可以通过重写此方法提供用户自定义的Dispatcher */protected Dispatcher createDispatcher(FilterConfig filterConfig){Map<String,String> params = new HashMap<String,String>();for(Enumeration e = fitlerConfig.getIntParameterNames();e.hasMoreElements();) {String e.nextElement();String value = filterConfig.getInitParameter(name);params.put(name,value);}return new Dispatcher(filterConfig.getServletContext(),params);}@Inject(StrutsConstants.STRUTS_SERVE_STATIC_CONTENT)public static void setServeStaticContent(String val){serveStatic = "true".equals(val);}@Inject(StrutsConstants.STRUTS_SERVE_STATIC_BROWSER_CACHE) public static void setServeStaticBrowserCache(String val) {serveStaticBrowserCache = "true".equals(val);}@Inject(StrutsConstants.STRUTS_I18N_ENCODING)public static void setEncoding(String val) {encoding = val;}@Injectpublic static void setActionMapper(ActionMapper mapper) {actionMapper = mapper;}/**某些版本的webLogic只能通过fitler config 返回servlet context对象,该方法解决了这个问题.**/protected ServletContext getServletContext() {return filterConfig.getServletContext();}protected FilterConfig getFilterConfig() {return filterConfig;}/**包装request对象,如果需要的话也可以根据给定的RQUEST用来处理多媒体类型*/protected HttpServletRequest prepareDispatcherAndWrapRequest(HttpServletRequest request,HttpServletResponse response)throws ServletException{Dispatcher du = Dispatcher.getInstance();//如果cleanUp filter 还没有准备好,程序将准备并且包装请求对象.//cleanup 过滤器必须配置在dispatcher filter对象的前面,因此当cleanup filter对象运行的时候,静态的dispatcher对象必须是nullif(du == null){Dispatcher.setInstance(dispatcher);dispatcher.prepare(request,response);}else{dispatcher = du;}try{request = dispatcher.wrapRequest(request,getServletContext());}catch(IOException e){String message = "Could not wrap servlet request with MultipartRequestWrapper!";LOG.error(message,e);throw new ServletException(message,e);}return request;}protected String[] parse(String packages){if(packages == null){return null;}List<String> pathPrefixes = new ArrayList<String>();StringT okenizer st = new StringT okenizer(packeages,", \n\t");while(st.hasMoreT okens()){String pathPrefix = st.nextToken.replace('.','/');if(!pathPrefix.endsWith("/")){pathPrefix+="/";}pathPrefixes.add(pathPrefix);}return pathPrefixes.toArray(new String[pathPrefixes.size()]);}public void doFilter(ServletRequest req,ServletResponse res,FilterChain chain)throws IOException,ServletException{HttpServletRequest request = (HttpServletRequest)req;HttpServletResponse response = (HttpServletResponse)res;ServletContext servletContext = getServletContext();String timerKey = "FilterDispatcher_doFilter:";try{UtilTimerStack.push(timerKey);request = prepareDispatcherAndWrapRequest(request,response);ActionMapping mapping;try{mapping = actionMapper.getMapping(request,dispatcher.getConfigurationManager());}catch(Exception ex){LOG.error("error getting ActionMapping",ex);dispatcher.sendError(request,response,servletContext,HttpServletResponse.SC_INTER NAL_SERVER_ERROR,ex);return;}if(mapping==null){//没有action被请求,是否查找静态资源String resourcePath = RequestUtils.getServletPath(request);if("".equals(resourcePath) && null != request.getPathInfo()){resourcePath = request.getPathInfo();}if(serveStatic && resourcePath.startsWith("/struts")){String /struts".length());findStaticResource(name,request,response);}else{chain.doFilter(request,response);}return;}dispatcher.serviceAction(request,response,servletContext,mapping);}finally{try{ActionContextCleanUp.cleanUp(req);}finally{UtilTimerStack.pop(timerKey);}}}protected void findStaticResource(String name,HttpServletRequest request,HttpServletResponse response)throws IOException{if(!name.endWith(".class")){for(String pathPrefix : pathPrefixes){InputStream is = findInputStream(name,pathPrefix);if(is !=null){Calendar cal = Calendar.getInstance();long ifModifiedSince = 0 ;try{ifModifiedSince = request.getDateHeader("If-Modified-Since");}catch(Exception e){LOG.warn("invalid If-Modified-Since header value:'"+request.getHeader("If-Modified-Since")+"', ignoring");}long lastModifiedMillis = lastModifiedCal.getTimeInMillis();long now = cal.getTimeMillis();cal.add(Calendar.DAY_OF_MONTH,1);long expires = cal.getTimeInMillis();if(ifModifiedSince >0 && ifModiifedSince <= lastModifiedMillis){response.setDateHeader("Expires",expires);response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);is.close();return;}//设置content-typeString contentType = getContentType(name);if(contentType != null){response.setContentType(contentType);}if(serveStaticBrowserCache){response.setDateHeader("Date",now);response.setDateHeader("Expires",expires);response.setDateHeader("Retry-After",expires);response.setHeader("Cache-Control","public");response.setDateHeader("Last-Modified",lastModifiedMillis);}else{response.setHeader("Cache-Control","no-cache");response.setHeader("Pragma","no-cache");response.setHeader("Expires","-1");}try{copy(is,response.getOutputStream());}finally{is.close();}return;}}}response.sendError(HttpServletResponse.SC_NOT_FOUND); }protected String getContentType(String name){if (name.endsWith(".js")){return "text/javascript";}else if (name.endsWith(".css")){return "text/css";}else if (name.endsWith(".html")){return "text/html";}else if (name.endsWith(".txt")){return "text/plain";}else if (name.endsWith(".gif")){return "image/gif";}else if (name.endsWith(".jpg") || name.endsWith(".jpeg")){return "image/jpeg";} else if (name.endsWith(".png")){return "image/png";} else{return null;}}protected void copy(InputStream input, OutputStream output) throws IOException {final byte[] buffer = new byte[4096];int n;while (-1 != (n = input.read(buffer))) {output.write(buffer, 0, n);}output.flush(); // WW-1526}protected InputStream findInputStream(String name, String packagePrefix) throws IOException{String resourcePath;if (packagePrefix.endsWith("/") && name.startsWith("/")){resourcePath = packagePrefix + name.substring(1);} else{resourcePath = packagePrefix + name;}resourcePath = URLDecoder.decode(resourcePath, encoding);return ClassLoaderUtil.getResourceAsStream(resourcePath, getClass());}}。
struts2_异常处理
Struts2___异常处理Struts2提供声明式的异常处理方式,内部通过配置的拦截器来实现,默认异常拦截器:com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor这样我们不需要在Action方法中catch异常,只需抛出相关的异常,都交由拦截器处理通过异常映射配置:<exception-mapping>元素exception属性:指定该异常映射所设置的异常类型result属性:指定Action出现该异常时,跳转到result属性所指向的结果异常映射类别分为两种:局部异常映射:<exception-mapping>配置<action name="exceptionAction"class="org.struts2.ch6.action.ExceptionAction"> <!-- 局部异常映射当Action 抛出指定异常时显示名为book_error指定的页面--><exception-mapping result="book_error"exception="ng.IllegalArgumentException"/><result>/ch6/book_add.jsp</result><result name="book_error">/ch6/book_error.jsp</result></action>全局异常映射:<global-exception-mappings>和<exception-mapping>配置<global-results><result name="error">/ch6/error.jsp</result></global-results><global-exception-mappings><exception-mapping result="error"exception="ng.Exception"/> </global-exception-mappings>页面输出异常信息:异常对象被封装成ExceptionHolder对象,压入ValueStack中<s:property value="exception.message"/> 输出异常对象消息<s:property value="exceptionStack"/> 输出异常堆栈信息Struts2 拦截器工作原理UML时序图:Struts2___类型转换◆内置的类型转换Stringboolean/Booleanchar/Characterint/Integer,float/Float,long/Long,double/Double date 默认时间格式为yyyy-MM-dd(当前时区的SHORT格式)数组假设每个单独的字符串都能转换成数组中元素的类型集合如果不能确定集合中元素的类型,会默认是String类型,并创建一个新的ArrayList对象◆自定义类型转换器主要方式:a.继承DefaultTypeConverter,重写convertValue方法b.继承StrutsTypeConverter,重写convertFromString和convertToString方法(推荐)public class DateTypeConverter extends StrutsTypeConverter {private String[] pattern = {"yyyy-MM-dd HH:mm:ss","yyyy/MM/dd HH:mm:ss","yyyy-MM-dd","yyyy/MM/dd"};private SimpleDateFormat sdf=new SimpleDateFormat();/*** @param context action上下文* values[] 需要转换的String数组* toClass 转换后的目标类型** @return返回转换后的目标对象*/public Object convertFromString(Map context, String[] values, Class toClass) { /** 使用指定的日期格式解析字符串值,返回Date对象*/Date date=null;if(toClass==Date.class && values.length>0){if(values[0]!=null && !"".equals(values[0])){System.out.println("接收的参数值:"+values[0]);date=parse(values[0]);if(date==null){/** 解析出现异常,抛出TypeConversionException异常,以通知Struts2发生了转换错误*/System.out.println("抛出类型转换异常,通知struts处理");throw new TypeConversionException("类型转换异常");}}System.out.println("转换后的值:"+date);return date;}return null;}public String convertToString(Map context, Object o) {/**使用指定的日期格式格式化Date对象,返回字符串*/return sdf.format(o);private Date parse(String source) {for(String fmt:pattern){Date d=convert(source,fmt);if(d!=null){return d;}}return null;}private Date convert(String source, String fmt) { try {sdf.applyPattern(fmt);Date v = sdf.parse(source);return v;}catch (ParseException e) {return null;}}自定义类型转换器的注册方式:A、局部类型转换器:针对某个ActionB、全局类型转换器:针对所有ActionC、使用JDK1.5的注释1.局部类型转换器提供如下格式的properties 文件,存放在Action类同一路径下文件名:action类名-conversion.properties内容: Action属性名=转换器全路径类名如:birthday=org.struts2.ch6.conversion.DateTypeConverter2、全局类型转换器(一般使用)提供如下格式的文件,存放位置:WEB-INF/classes/目录下文件名: xwork-conversion.properties内容:需要转换的全路径的类名=转换器全路径类名如:java.Util.Date=org.struts2.ch6.conversion.DateTypeConverter 类型转换的流程(String转对应类型)类型转换异常提示处理类型转换由conversionError拦截器处理出错返回input指向页面使用<s:fielderror/>显示错误信息##默认类型转换错误消息(一般使用) 一般定义在全局资源包文件中xwork.default.invalid.fieldvalue=this.field{0}value invalid ##局部类型转换错误消息显示(一般定义action级别资源包)invalid.fieldvalue.属性名=错误提示invalid.fieldvalue.birthday=birthday convert error!!!示例参见ch6。
Struts2 中拦截器和Action的调用关系
</action>
<action name="action2" class="com.suo.actions.Action2">
this.password = password;
}
public String execute()
{
System.out.println("action2 invoke !");
return SUCCESS;
}
public String execute()
{
System.out.println("action1 invoke !");
return SUCCESS;
}
}
复制代码
复制代码
Action2.java:
public class MyInterceptor implements Interceptor {
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("destroy invoke !");
}
@Override
public void init() {
// TODO Auto-generated method stub
System.out.println("init invoke !");
Struts2默认拦截器解析
Struts2默认拦截器解析使用struts2,拦截器大家经常使用,当然默认情况我们除了自定义的拦截器外,会使用struts2默认的拦截器,那他究竟有哪些默认的拦截器?每个拦截器都是做什么的呢?我们来看下对应的源码,打开对应源码下的struts2-default.xml文件我们可以看到对应很多的拦截器信息,如下<interceptors><interceptor name="alias"class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/><interceptor name="autowiring"class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInt erceptor"/><interceptor name="chain"class="com.opensymphony.xwork2.interceptor.ChainingInterceptor"/> <interceptor name="conversionError"class="org.apache.struts2.interceptor.StrutsConversionErrorIntercepto r"/><interceptor name="cookie"class="org.apache.struts2.interceptor.CookieInterceptor"/><interceptor name="createSession"class="org.apache.struts2.interceptor.CreateSessionInterceptor"/> <interceptor name="debugging"class="org.apache.struts2.interceptor.debugging.DebuggingInterceptor" /><interceptor name="externalRef"class="com.opensymphony.xwork2.interceptor.ExternalReferencesInterceptor"/><interceptor name="execAndWait"class="org.apache.struts2.interceptor.ExecuteAndWaitInterceptor"/> <interceptor name="exception"class="com.opensymphony.xwork2.interceptor.ExceptionMappingIntercepto r"/><interceptor name="fileUpload"class="org.apache.struts2.interceptor.FileUploadInterceptor"/> <interceptor name="i18n"class="com.opensymphony.xwork2.interceptor.I18nInterceptor"/><interceptor name="logger"class="com.opensymphony.xwork2.interceptor.LoggingInterceptor"/> <interceptor name="modelDriven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> <interceptor name="scopedModelDriven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenIntercept or"/><interceptor name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/> <interceptor name="prepare"class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/> <interceptor name="staticParams"class="com.opensymphony.xwork2.interceptor.StaticParametersIntercepto r"/><interceptor name="scope"class="org.apache.struts2.interceptor.ScopeInterceptor"/><interceptor name="servletConfig"class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> <interceptor name="sessionAutowiring"class="org.apache.struts2.spring.interceptor.SessionContextAutowiring Interceptor"/><interceptor name="timer"class="com.opensymphony.xwork2.interceptor.TimerInterceptor"/> <interceptor name="token"class="org.apache.struts2.interceptor.TokenInterceptor"/><interceptor name="tokenSession"class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/> <interceptor name="validation"class="org.apache.struts2.interceptor.validation.AnnotationValidation Interceptor"/><interceptor name="workflow"class="com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor "/><interceptor name="store"class="org.apache.struts2.interceptor.MessageStoreInterceptor"/> <interceptor name="checkbox"class="org.apache.struts2.interceptor.CheckboxInterceptor"/><interceptor name="profiling"class="org.apache.struts2.interceptor.ProfilingActivationInterceptor" /><interceptor name="roles" class="org.apache.struts2.interceptor.RolesInterceptor"/> <!-- Deprecated name forms scheduled for removal in Struts 2.1.0. The camelCase versions are preferred. See ww-1707 --><interceptor name="external-ref"class="com.opensymphony.xwork2.interceptor.ExternalReferencesIntercep tor"/><interceptor name="model-driven"class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/> <interceptor name="static-params"class="com.opensymphony.xwork2.interceptor.StaticParametersIntercepto r"/><interceptor name="scoped-model-driven"class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenIntercept or"/><interceptor name="servlet-config"class="org.apache.struts2.interceptor.ServletConfigInterceptor"/> <interceptor name="token-session" class="org.apache.struts2.interceptor.TokenSessionStoreInterceptor"/><!-- Basic stack --><interceptor-stack name="basicStack"><interceptor-ref name="exception"/><interceptor-ref name="servletConfig"/><interceptor-ref name="prepare"/><interceptor-ref name="checkbox"/><interceptor-ref name="params"/><interceptor-ref name="conversionError"/></interceptor-stack><!-- Sample validation and workflow stack --><interceptor-stack name="validationWorkflowStack"><interceptor-ref name="basicStack"/><interceptor-ref name="validation"/><interceptor-ref name="workflow"/></interceptor-stack><!-- Sample file upload stack --><interceptor-stack name="fileUploadStack"><interceptor-ref name="fileUpload"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- Sample model-driven stack --><interceptor-stack name="modelDrivenStack"><interceptor-ref name="modelDriven"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- Sample action chaining stack --><interceptor-stack name="chainStack"><interceptor-ref name="chain"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- Sample i18n stack --><interceptor-stack name="i18nStack"><interceptor-ref name="i18n"/><interceptor-ref name="basicStack"/></interceptor-stack><!-- An example of the params-prepare-params trick. This stack is exactly the same as the defaultStack, except that itincludes one extra interceptor before the prepare interceptor:the params interceptor.This is useful for when you wish to apply parameters directlyto an object that you wish to load externally (such as a DAOor database or service layer), but can't load that objectuntil at least the ID parameter has been loaded. By loadingthe parameters twice, you can retrieve the object in theprepare() method, allowing the second params interceptor toapply the values on the object. --><interceptor-stack name="paramsPrepareParamsStack"><interceptor-ref name="exception"/><interceptor-ref name="alias"/><interceptor-ref name="params"/><interceptor-ref name="servletConfig"/><interceptor-ref name="prepare"/><interceptor-ref name="i18n"/><interceptor-ref name="chain"/><interceptor-ref name="modelDriven"/><interceptor-ref name="fileUpload"/><interceptor-ref name="checkbox"/><interceptor-ref name="staticParams"/><interceptor-ref name="params"/><interceptor-ref name="conversionError"/><interceptor-ref name="validation"><paramname="excludeMethods">input,back,cancel</param></interceptor-ref><interceptor-ref name="workflow"><paramname="excludeMethods">input,back,cancel</param></interceptor-ref></interceptor-stack><!-- A complete stack with all the common interceptors in place.Generally, this stack should be the one you use, though itmay do more than you need. Also, the ordering can beswitched around (ex: if you wish to have yourservlet-relatedobjects applied before prepare() is called, you'd need to moveservlet-config interceptor up.This stack also excludes from the normal validation and workflowthe method names input, back, and cancel. These typically areassociated with requests that should not be validated.--><interceptor-stack name="defaultStack"><interceptor-ref name="exception"/><interceptor-ref name="alias"/><interceptor-ref name="servletConfig"/><interceptor-ref name="prepare"/><interceptor-ref name="i18n"/><interceptor-ref name="chain"/><interceptor-ref name="debugging"/><interceptor-ref name="profiling"/><interceptor-ref name="scopedModelDriven"/><interceptor-ref name="modelDriven"/><interceptor-ref name="fileUpload"/><interceptor-ref name="checkbox"/><interceptor-ref name="staticParams"/><interceptor-ref name="params"><param name="excludeParams">dojo\..*</param></interceptor-ref><interceptor-ref name="conversionError"/><interceptor-ref name="validation"><paramname="excludeMethods">input,back,cancel,browse</param></interceptor-ref><interceptor-ref name="workflow"><paramname="excludeMethods">input,back,cancel,browse</param></interceptor-ref></interceptor-stack><!-- The completeStack is here for backwards compatibility for applications that still refer to the defaultStack by theold name --><interceptor-stack name="completeStack"><interceptor-ref name="defaultStack"/></interceptor-stack><!-- Sample execute and wait stack.Note: execAndWait should always be the *last* interceptor. --><interceptor-stack name="executeAndWaitStack"><interceptor-ref name="execAndWait"><paramname="excludeMethods">input,back,cancel</param></interceptor-ref><interceptor-ref name="defaultStack"/><interceptor-ref name="execAndWait"><paramname="excludeMethods">input,back,cancel</param></interceptor-ref></interceptor-stack><default-interceptor-ref name="defaultStack"/>是配置对应的拦截器栈,下面我们来看对应的拦截器栈都有哪些?都是做什么的?如果不配置拦截器,默认使用他自己的defaultStack,我们看到,defaultStack包含了基本上所有的拦截器,所以基本上都能满足我们的需求,但是我们一般情况下用不了这么多拦截器栈的,经过这么多拦截器栈肯定会影响性能的,所以我们可以根据不通的场景,选择合适的拦截器栈。
Interceptor的基本介绍和使用
Interceptor的基本介绍和使⽤简介java⾥的拦截器是动态拦截Action调⽤的对象,它提供了⼀种机制可以使开发者在⼀个Action执⾏的前后执⾏⼀段代码,也可以在⼀个Action执⾏前阻⽌其执⾏,同时也提供了⼀种可以提取Action中可重⽤部分代码的⽅式。
在AOP中,拦截器⽤于在某个⽅法或者字段被访问之前,进⾏拦截然后再之前或者之后加⼊某些操作。
⽬前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不⽤深究,知道即可。
原理⼤部分时候,拦截器⽅法都是通过代理的⽅式来调⽤的。
Struts2的拦截器实现相对简单。
当请求到达Struts2的ServletDispatcher时,Struts2会查找配置⽂件,并根据配置实例化相对的拦截器对象,然后串成⼀个列表(List),最后⼀个⼀个的调⽤列表中的拦截器。
Struts2的拦截器是可插拔的,拦截器是AOP的⼀个实现。
Struts2拦截器栈就是将拦截器按⼀定的顺序连接成⼀条链。
在访问被拦截的⽅法或者字段时,Struts2拦截器链中的拦截器就会按照之前定义的顺序进⾏调⽤。
⾃定义拦截器的步骤第⼀步:⾃定义⼀个实现了Interceptor接⼝的类,或者继承抽象类AbstractInterceptor。
第⼆步:在配置⽂件中注册定义的拦截器。
第三步:在需要使⽤Action中引⽤上述定义的拦截器,为了⽅便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的Action都被这个拦截器拦截。
Spring拦截器5.1,抽象类HandlerInterceptorAdapter我们如果在项⽬中使⽤了Spring框架,那么,我们可以直接继承HandlerInterceptorAdapter.java这个抽象类,来实现我们⾃⼰的拦截器。
框架,对java的拦截器概念进⾏了包装,这⼀点和Struts2很类似。
HandlerInterceptorAdapter继承了抽象接⼝HandlerInterceptor。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
public static final String LOGIN_KEY = "LOGIN";
public static final String LOGIN_PAGE = "global.login";
public String intercept(ActionInvocation actionInvocation) throws Exception {
</interceptor-stack>
</interceptors>
将上述拦截器设定为默认拦截器:
<default-interceptor-ref name="teamwareStack"/>
这样在后续同一个package内部的所有Action执行之前都会被login拦截。
<result>/jsp/smeishop/admin/logon.jsp</result>
</action>
</package>
你的拦截器可以正常工作了!!HOHO
以下是参考资料
struts2自带的配置及其拦截器配置
Struts2 拦截器 [Interceptor]
的情况下所有的Action都被这个拦截器拦截。
Interceptor接口声明了三个方法:
public interface Interceptor extends Serializable {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
}
}
注册拦截器
<interceptors>
<interceptor
name="login"
class="com.jpleasure.teamware.util.CheckLoginInterceptor"/>
String login = (String) session.get(LOGIN_KEY);
if (login != null && login.length() > 0) {
// 存在的情况下进行后续操作。
System.out.println("already login!");
Intercept是拦截器的主要拦截方法,如果需要调用后续的Action或者拦截器,只需要在该方法中调用
invocation.invoke()方法即可,在该方法调用的前后可以插入Action调用前后拦截器需要做的方法。
如果不需要调用后续的方法,则返回一个String类型的对象即可,例如Action.SUCCESS。
如何使用struts2拦截器,或者自定义拦截器。特别注意,在使用拦截器的时候,在Action里面必须最后一定要引用struts2自带的拦截器缺省堆栈defaultStack,如下(这里我是引用了struts2自带的checkbox拦截器):
<interceptor-ref name="checkbox">
<param name="uncheckedValue">0</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
<interceptor-stack name="myStack">
<interceptor-ref name="checkbox">
<param name="uncheckedValue">0</param>
</package>
struts-action.xml里面配置Action如下:
<package name="LogonAdmin" extends="struts-shop">(这里扩展struts.xml里面定义的配置就可以了)
(必须加,否则出错)
也可以改为对全局Action设置自己需要的拦截器,如下:
在struts.xml里面定义全局的配置设置
<package name="struts-shop" extends="struts-default">
<interceptors>
<action name="logon" class="logonAction">
<result>/jsp/smeishop/admin/index.jsp</result>
<result name="error">/jsp/smeishop/admin/logon.jsp</result>
我们尝试编写一个Session过滤用的拦截器,该拦截器查看用户Session中是否存在特定的属性(LOGIN属性)
如果不存在,中止后续操作定位到LOGIN,否则执行原定操作,代码为:
public class CheckLoginInterceptor extends AbstractInterceptor {
另外AbstractInterceptor提供了一个简单的Interceptor的实现,这个实现为:
public abstract class AbstractInterceptor implements Interceptor {
public void init() {
}
<result name="input">/jsp/smeishop/admin/logon.jsp</result>
</action>
<action name="logout" class="logoutAction">
Cookies Interceptor
cookies
使用配置的name,value来是指cookies
Conversion Error Interceptor
conversionError
将错误从ActionContext中添加到Action的属性字段中。
Create Session Interceptor
public void destroy() {
}
public abstract String intercept(ActionInvocation invocation) throws Exception;
}
在不需要编写init和destroy方法的时候,只需要从AbstractInterceptor继承而来,实现intercept方法即可。
System.out.println("begin check login interceptor!");
// 对LoginAction不做该项拦截
Object action = actionInvocation.getAction();
if (action instanceof LoginAction) {
} Leabharlann Init方法在拦截器类被创建之后,在对Action镜像拦截之前调用,相当于一个post-constructor方法,
使用这个方法可以给拦截器类做必要的初始话操作。
Destroy方法在
拦截器被垃圾回收之前调用,用来回收init方法初始化的资源。
return actionInvocation.invoke();
} else {
// 否则终止后续操作,返回LOGIN
System.out.println("no login, forward login page!");
return LOGIN_PAGE;
chain
让前一个Action的属性可以被后一个Action访问,现在和chain类型的result(<result type=”chain”>)结合使用。