拦截器是struts2框架的核心,struts2很多的功能都是构建在拦截器基础之上的,它是动态拦截Action调用的对象,提供了一种机制,使得开发者能够在一个Action前后执行需要的代码,可以在一个Action执行前组织他的执行,也能在Action执行后做一些相应的工作。同时他也提供了一种可以提取Action中可重用部分的方式。
拦截器
struts2拦截器是在访问某个Action或它的某个方法 、字段之前或之后实施拦截,struts2拦截器是可插拔的,是AOP的一种实现(AOP是OOP(Object-Oriented Programming,面向对象程序设计)的一种完善和补充,是软件技术和设计思想发展到一定阶段的自然产物)
一般情况下,拦截器都是通过代理的方式进行调用,当请求到达Struts2的ServletDispatcher(Web HTTP请求的调度器,所有对Action的请求都将通过ServletDispatcher调用)时,struts2会查找配置文件,并且根据配置文件的配置实例化相对的拦截器对象,并形成一个列表。每个Action请求都包装在一系列的拦截器内部。拦截器可以在Action执行之前做准备操作。也可以在之后进行操作,每个Action即可以将操作转交给下面的拦截器,也可以直接退出操作。
拦截器的配置
在Web应用中引入拦截器机制之后,就能够实现对Action通用操作的可插拔管理方式,这样的可插拔管理是基于struts.xml文件的配置来实现的。
定义拦截器的语法格式如下:
<interceptor name="拦截器名字" class="拦截器对应的java类型"/>
拦截器栈的配置
<interceptors>
<interceptor-stack name="拦截器栈的名字">
<interceptor-ref name="拦截器的名字"/>
</interceptor>
</interceptors>
拦截器的实例:
能够实现文字过滤的拦截器
Action:
public class ContentAction extends ActionSupport{ private String name;//评论人 private String content;//评论内容 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String execute() throws Exception { return SUCCESS; } }
拦截器类:
public class ContentInterceptor extends AbstractInterceptor{ @Override public String intercept(ActionInvocation arg0) throws Exception { Object obj = arg0.getAction();//获取Action的实例 if(obj != null){ if(obj instanceof ContentAction){ ContentAction ca = (ContentAction)obj;//实例化ContentAction类 String content = ca.getContent();//获得用户提交的评论信息 int startIndex = content.indexOf('人');//检测字符人出现的位置 //截取从人开始往后的三个字符串 String str = content.substring(startIndex,startIndex + 3); //如果用户发表的评论中包含有要过滤的文字 if(str.equals("人品差")){ content = content.replaceAll("人品差", "*");//以*替换要过滤的文字 ca.setContent(content);//将替换后的内容赋值给content属性 } return arg0.invoke(); }else{ return Action.LOGIN; } } return Action.LOGIN; } }
重要的一步,在struts.xml中的配置
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.i18n.encoding" value="UTF-8"/> <package name="default" extends="struts-default" namespace="/"> <interceptors> <interceptor name="contentItp" class="com.mxl.interceptor.ContentInterceptor"/> </interceptors> <action name="content" class="com.mxl.actions.ContentAction"> <result>/content_success.jsp</result> <result name="login">/content_send.jsp</result> <interceptor-ref name="defaultStack"/> <interceptor-ref name="contentItp"/> </action> </package> </struts>
两个简单的页面:
content_send.xml:
<s:form action="content.action" method="post"> <s:textfield name="name" label="评论人" size="81"/> <s:textfield name="content" label="评论正文" cols="180" rows="120"/> <s:checkbox name="arr" label="我已阅读并同意当当网社区条款"/> <s:submit type="button" align="center"/> </s:form>
content_success.jsp:
<table cellpadding="0" cellspacing="0" border="0" align="left"> <tr style="line-height:30px;"> <td style="font-size:14px;font-weight:bold;" align="left"> 对Spring入门经典的评论 </td></tr> <tr> <td style="font-size:12px;"> 评论人:<s:property value="name"/> </td> </tr> <tr> <td style="font-size:12px"> 评论正文:<s:property value="content"/> </td> </tr> </table>
不要忘了在开头的地方加上,<%@ taglib prefix="s" uri="/struts-tags" %>,
拦截器的方法过滤实例:
拦截器类:
public class LoginInterceptor extends MethodFilterInterceptor{ @Override protected String doIntercept(ActionInvocation arg0) throws Exception { Map session=arg0.getInvocationContext().getSession();//获取Session对象 String uname = (String)session.get("username");//获取session中的username对象,并赋值给uname变量 System.out.println(uname + "XXXXXXXXXXXXX"); if(uname != null && !uname.equals("")){//检测uname变量的值,如果不为NULL或不为"",则进行后续操作 return arg0.invoke(); }else{//否则,重新登陆 session.put("errorMsg", "您还未登录,请登录!"); return Action.LOGIN; } } }
Action类:
public class UserAction extends ActionSupport{ private String username; private String pwd; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String execute() throws Exception { return SUCCESS; } public String login(){ if("admin".equals(username.trim())){ ActionContext ac = ActionContext.getContext(); ac.getSession().put("username", username); return SUCCESS; }else{ this.addFieldError("username", "用户名/密码错误"); return LOGIN; } } }
struts.xml中的配置:
<interceptors> <interceptor name="myitp" class="com.mxl.interceptor.LoginInterceptor"/> </interceptors> <action name="timer" class="com.mxl.actions.TimerAction"> <result>/index.jsp</result> <interceptor-ref name="timer"/> </action> <action name="login" class="com.mxl.actions.UserAction"> <result>/success.jsp</result> <result name="login">/login.jsp</result> <interceptor-ref name="defaultStack"/> <interceptor-ref name="myitp"> <param name="excludeMethods">login</param> </interceptor-ref> </action>
两个页面:
login.jsp:
<font color="red" style="font-size:12px"><s:property value="#session.errorMsg"/></font> <s:form action="login!login.action" method="post"> <s:textfield name="username" label="用户名" size="20"/> <s:password name="pwd" label="密码" size="20"/> <s:submit type="button" value="登录"/> </s:form>
success.jsp:
<s:if test="#session.username==null"> <font color="red">您还未登录,不能对本站进行任何操作,请<s:a href="login.action" namespace="/">登录</s:a>!</font> </s:if> <s:else> 欢迎您:<s:property value="#session.username"/> </s:else>