struts2自定义拦截器
2016-12-27 23:30
591 查看
struts2拦截器的结构图
自定义拦截器编写
定义一个拦截器
从上面的其结构图来看,我们要定义一个拦截器,只需继承AbstractInterceptor或者实现Interceptor接口,然后实现intercept方法public class MyInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println("自定义拦截器执行了"); return null; } }
现在创建了一个拦截器就可以使用了嘛,当然不是,
配置该拦截器使用
配置拦截器使用有两个步骤第一:声明拦截器(在使用前一定要声明)]
<package name="p1" extends="struts-default" > <!--声明拦截器 --> <interceptors> <interceptor name="myinterceptor" class="com.yu.web.action.MyInterceptor"></interceptor> </interceptors>
第二步:使用拦截器
<action name="hello" class="com.yu.web.action.HelloAction" method="saveUser"> <!--使用拦截器,使用拦截器之前,必须声明它 --> <!--在这里配置拦截器之后,默认配置的拦截器将会失效 --> <interceptor-ref name="myinterceptor"></interceptor-ref> <result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 --> <result name="exists">/message.jsp</result><!-- 当用户名已经存在之后,转向的结果视图 --> <result name="input">/register.jsp</result> </action>
测试拦截器是否起作用,触发上面配置的action
而我们的动作方法是:
public String saveUser(){ System.out.println("动作方法执行了"); return SUCCESS; }
所以看到,动作方法并没有执行,这是什么原因了,我们看struts2的结构流程图可知,动作方法执行之前是先执行其拦截器的,我们在前面的拦截器中只是打印了y一句话,并没有做其它操作,我们想要动作方法也执行,就必须放行此拦截器。
public class MyInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println("自定义拦截器执行了"); String result=invocation.invoke(); //放行次拦截器向下执行 //执行完结果视图后,反向执行拦截器 System.out.println("反向执行"); //放行后结果返回的结果是结果视图的名称 System.out.println(result); return null; } }
打印结果:
自定义拦截器执行了
动作方法执行了
反向执行
多个拦截器的执行顺序
创建一个同样的interceptorimport com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor2 extends 4000 AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println("自定义拦截器2执行了"); String result=invocation.invoke(); //放行次拦截器向下执行 //执行完结果视图后,反向执行拦截器 System.out.println("自定义拦截器2反向执行"); //放行后结果返回的结果是结果视图的名称 System.out.println(result+"视图结果"); return null; } }
声明和配置定义过滤器
<package name="p1" extends="struts-default" > <!--声明拦截器 --> <interceptors> <interceptor name="myinterceptor1" class="com.yu.web.action.MyInterceptor1"></interceptor> <interceptor name="myinterceptor2" class="com.yu.web.action.MyInterceptor2"></interceptor> </interceptors> <action name="findAll" class="com.yu.web.action.HelloAction" method="findAll"> <result>/findall.jsp</result> </action> <action name="hello" class="com.yu.web.action.HelloAction" method="saveUser"> <!--使用拦截器,使用拦截器之前,必须声明它 --> <!--在这里配置拦截器之后,默认配置的拦截器将会失效 --> <interceptor-ref name="myinterceptor1"></interceptor-ref> <interceptor-ref name="myinterceptor2"></interceptor-ref> <result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 --> <result name="exists">/message.jsp</result><!-- 当用户名已经存在之后,转向的结果视图 --> <result name="input">/register.jsp</result> </action> </package>
打印结果:
自定义拦截器1执行了
自定义拦截器2执行了
动作方法执行了
自定义拦截器2反向执行
自定义拦截器1反向执行
如果我们改变拦截器配置的顺序
<interceptor-ref name="myinterceptor2"></interceptor-ref> <interceptor-ref name="myinterceptor1"></interceptor-ref>
打印结果:
自定义拦截器2执行了
自定义拦截器1执行了
动作方法执行了
自定义拦截器1反向执行
自定义拦截器2反向执行
所以从上面可以看到,拦截器的执行顺序和配置拦截器的顺序有关
intercept的返回值
其放行方法有个返回值,我们可以打印此值,看其结果.@Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub System.out.println("自定义拦截器2执行了"); String result=invocation.invoke(); //放行次拦截器向下执行 //执行完结果视图后,反向执行拦截器 System.out.println("自定义拦截器2反向执行"); System.out.println(result); return result; }
打印结果:
自定义拦截器1执行了
动作方法执行了
jsp执行了
自定义拦截器1反向执行
success
自定义拦截器2反向执行
success
从上面可以看到,拦截器返回的就是其结果视图
拦截器的一个应用
在没有登录之前,不能查看其它页面。 那么就给其它页面一个检查是否已经登录的拦截器拦截器:
@Override public String intercept(ActionInvocation invocation) throws Exception { // TODO Auto-generated method stub //获取登陆标志 HttpSession session = ServletActionContext.getRequest().getSession(); //有user标志,表示已经登录 Object obj=session.getAttribute("user"); if(obj!=null){ String result= invocation.invoke(); return result; }else{ //如果没有登录,则返回到登录页面 return "register"; } }
拦截器配置:
<action name="findAll" class="com.yu.web.action.HelloAction" method="findAll"> <interceptor-ref name="myinterceptor1"></interceptor-ref> <result>/findall.jsp</result> <result name="register">/register.jsp</result> </action>
触发此action,发现,如果没有登录标记,就会跳到登录页面.
先登录设置一个登录标记,检测是否可以进入其它页面
设置登录标记
public String saveUser(){ HttpSession session = ServletActionContext.getRequest().getSession(); session.setAttribute("user", "aaa"); System.out.println("动作方法执行了"); return SUCCESS; }
现在可以进入其它页面
存在的问题
问题一:上述配置自己的拦截器后,默认的拦截器不起作用了,a.解决办法:加入默认的拦截器
<action name="findAll" class="com.yu.web.action.HelloAction" method="findAll"> <!--为什么是defaultStack了,因为struts-default.xml文件中 所有默认拦截器的栈名是defaultStack --> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="myinterceptor1"></interceptor-ref> <result>/findall.jsp</result> <result name="register">/register.jsp</result> </action>
b.上述办法也会出现一个问题
当有拦截器,多个动作要写配置多个拦截器的时候,这样写比较麻烦,解决办法是可以,配置一个全局的拦截器栈
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="com.yu.web.resources.message"></constant>
<package name="mydefault" extends="struts-default">
<!--声明拦截器 -->
<interceptors>
<interceptor name="myinterceptor1" class="com.yu.web.action.MyInterceptor1"></interceptor>
<interceptor name="myinterceptor2" class="com.yu.web.action.MyInterceptor2"></interceptor>
<!--声明拦截器栈 -->
<interceptor-stack name="mydefaultStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myinterceptor1"></interceptor-ref>
</interceptor-stack>
</interceptors>
</package>
<!--注意:现在继承mydefault -->
<package name="p1" extends="mydefault" >
<action name="findAll" class="com.yu.web.action.HelloAction" method="findAll">
<!--为什么是defaultStack了,因为struts-default.xml文件中 所有默认拦截器的栈名是defaultStack -->
<interceptor-ref name="mydefaultStack"></interceptor-ref>
<result>/findall.jsp</result>
<result name="register">/register.jsp</result>
</action>
<action name="hello" class="com.yu.web.action.HelloAction" method="saveUser">
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="exists">/message.jsp</result><!-- 当用户名已经存在之后,转向的结果视图 -->
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
c.上述办法虽然解决了写多个拦截器的麻烦
但是仍然每个动作方法都要配置其拦截器,那有没直接配置一个就可以的了,当然,默认拦截器,我们并没有配置,但是执行每个动作方法前,都有被执行,其实,在struts-default.xml中,有配置默认的拦截器
<default-interceptor-ref name="defaultStack"/>
所以,我们也可以配置一个默认的拦截器
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="com.yu.web.resources.message"></constant>
<package name="mydefault" extends="struts-default">
<!--声明拦截器 -->
<interceptors>
<interceptor name="myinterceptor1" class="com.yu.web.action.MyInterceptor1"></interceptor>
<interceptor name="myinterceptor2" class="com.yu.web.action.MyInterceptor2"></interceptor>
<!--声明拦截器栈 -->
<interceptor-stack name="mydefaultStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myinterceptor1"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!--默认拦截器栈 -->
<default-interceptor-ref name="mydefaultStack"></default-interceptor-ref>
</package>
<!--注意:现在继承mydefault -->
<package name="p1" extends="mydefault" >
<action name="findAll" class="com.yu.web.action.HelloAction" method="findAll">
<result>/findall.jsp</result>
<result name="register">/register.jsp</result>
</action>
<action name="hello" class="com.yu.web.action.HelloAction" method="saveUser">
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="exists">/message.jsp</result><!-- 当用户名已经存在之后,转向的结果视图 -->
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
d.在使用了默认拦截器后,就给所有的动作方法都加上了拦截器
但是可能我们有些动作方法不需要加拦截器,这个怎么解决了
AbstractInterceptor有个子类,MethodFilterInterceptor,它有两个方法
public void setExcludeMethods(String excludeMethods) {
this.excludeMethods = TextParseUtil.commaDelimitedStringToSet(excludeMethods);
}
public void setIncludeMethods(String includeMethods) {
this.includeMethods = TextParseUtil.commaDelimitedStringToSet(includeMethods);
}
这两个方法表示,在一个拦截器中,可以配置那些方法不拦截,那些方法拦截
setIncludeMethods:表示拦截那些方法
setExcludeMethods:表示不拦截那些方法
首先:自定义拦截器继承MethodFilterInterceptor
public class MyInterceptor1 extends MethodFilterInterceptor {
@Override
public String doIntercept(ActionInvocation invocation) throws Exception {
// TODO Auto-generated method stub
//获取登陆标志
HttpSession session = ServletActionContext.getRequest().getSession();
//有user标志,表示已经登录
Object obj=session.getAttribute("user");
if(obj!=null){
String result= invocation.invoke();
return result;
}else{
//如果没有登录,则返回到登录页面
return "register";
}
}
}
为什么重写方法是doIntercept,难道是拦截器的方法改变了嘛,当然不是,拦截器执行的默认方法还是intercept(ActionInvocation invocation)这个方法,只是
MethodFilterInterceptor中intercept(ActionInvocation invocation)调用的是 doIntercept(ActionInvocation invocation)
@Override
public String intercept(ActionInvocation invocation) throws Exception {
if (applyInterceptor(invocation)) {
return doIntercept(invocation);
}
return invocation.invoke();
}
现在,我们配置我们要哪个方法需要拦截,哪个方法不需要,比如,我们在登录的时候,不需要检测用户是否登录
在申明拦截器栈的拦截器中配置(因为声明拦截器栈的过程中,相当于调用了拦截器)
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<constant name="struts.custom.i18n.resources" value="com.yu.web.resources.message"></constant>
<package name="mydefault" extends="struts-default">
<!--声明拦截器 -->
<interceptors>
<interceptor name="myinterceptor1" class="com.yu.web.action.MyInterceptor1"></interceptor>
<interceptor name="myinterceptor2" class="com.yu.web.action.MyInterceptor2"></interceptor>
<!--声明拦截器栈 -->
<interceptor-stack name="mydefaultStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="myinterceptor1">
<param name="excludeMethods">login</param>
</interceptor-ref>
</interceptor-stack>
</interceptors>
<!--默认拦截器栈 -->
<default-interceptor-ref name="mydefaultStack"></default-interceptor-ref>
</package>
<!--注意:现在继承mydefault -->
<package name="p1" extends="mydefault" >
<action name="findAll" class="com.yu.web.action.HelloAction" method="findAll">
<result>/findall.jsp</result>
<result name="register">/register.jsp</result>
</action>
<action name="hello" class="com.yu.web.action.HelloAction" method="saveUser">
<result>/success.jsp</result><!-- 当注册成功之后重定向的结果视图 -->
<result name="exists">/message.jsp</result><!-- 当用户名已经存在之后,转向的结果视图 -->
<result name="input">/register.jsp</result>
</action>
</package>
</struts>
e.上述解决就已经完善了嘛,当然不是
我们在登录之前,拦截器怎么知道,我们的动作方法叫什么了,解决办法是,在动作方法中,注入其参数
<action name="login" class="com.yu.web.action.HelloAction" method="login">
<param name="myinterceptor1.excludeMethods">login</param>
<result>/success.jsp</result>
</action>
相关文章推荐
- Struts2 输入验证与自定义拦截器
- struts2自定义拦截器
- Struts2自定义拦截器
- struts2总结(4)自定义拦截器
- struts2自定义拦截器
- struts2的拦截器自定义,使用默认拦截器,组合拦截器堆 的案例
- Struts2自定义拦截器
- Struts2 自定义日志 拦截器 interceptor
- struts2自定义拦截器
- Struts2---自定义拦截器
- struts2中的自定义拦截器
- 初学Struts2-自定义拦截器及其配置
- struts2自定义拦截器一——模拟登陆权限验证
- Struts2自定义拦截器—Session超时的处理
- struts2自定义拦截器的实现及使用
- Struts2 自定义拦截器(方法拦截器)
- struts2多个自定义拦截器的栈
- Struts2自定义拦截器
- Struts2自定义拦截器实例—登陆权限验证
- struts2 加入自定义拦截器后,原来能用的登录页出错