Filter、Interceptor都是AOP思想的体现。
Filter(过滤器)会拦截所有的请求,对html、jsp、Servlet等资源的请求都会被拦截。
Interceptor(拦截器)只拦截对Action的请求,且可以实现细粒化拦截,可以只拦截Action中的部分方法。
Filter、Interceptor的执行顺序都是:去的时候依次执行1,2,3,回来的时候就依次执行3,2,1。
因为是在1里面放行,调用2,在2里面放行,调用3,3里面放行调用Action|Servlet|JSP|html,得到响应对象,
响应对象返还给3,3对响应对象进行处理,返回给2,2对响应对象进行处理,返回给1,1对响应对象进行处理,返回给服务器,服务器返回给浏览器。
相当于递归调用。
注意是先调用JSP,由JSP组成响应,再由拦截器对响应进行进一步处理。
拦截器能拦截请求,也能拦截响应。
<struts> <package name="action" namespace="/action" extends="struts-default"> <interceptors> <interceptor name="" class=""></interceptor> <interceptor-stack name=""> <interceptor-ref name=""></interceptor-ref> <interceptor-ref name=""></interceptor-ref> <interceptor-ref name=""></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name=""></default-interceptor-ref> <action name="" class=""> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name=""></interceptor-ref> <result name=""></result> <result name=""></result> </action> </package> </struts>
在<interceptors>中注册拦截器、拦截器栈,注册之后就可以通过name来引用拦截器、拦截器栈。可以用拦截器栈来组合一组拦截器。
<default-interceptor-ref name=""></default-interceptor-ref>配置默认引用的拦截器、拦截器栈,此配置会覆盖struts-default.xml中的默认拦截器配置。如果我们配置了拦截器、拦截器栈的引用,就不会再自动调用默认的;如果我们没有配置拦截器、拦截器栈的引用,会自动调用默认的。
<interceptors>、<default-interceptor-ref>均只能作为<package>的子元素来配置。
在<action>中使用<interceptor-ref>来引用拦截器、拦截器栈,可同时引用多个,默认拦截器栈中有很多通用处理,一般都要引用。
<interceptor-ref>只能作为<action>的子元素来配置。
struts-default.xml中的默认拦截器配置:
<interceptor-stack name="defaultStack"> <interceptor-ref name="exception"/> <interceptor-ref name="alias"/> <interceptor-ref name="servletConfig"/> <interceptor-ref name="i18n"/> <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="scopedModelDriven"/> <interceptor-ref name="modelDriven"/> <interceptor-ref name="fileUpload"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="datetime"/> <interceptor-ref name="multiselect"/> <interceptor-ref name="staticParams"/> <interceptor-ref name="actionMappingParams"/> <interceptor-ref name="params"/> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse</param> </interceptor-ref> <interceptor-ref name="debugging"/> </interceptor-stack>
<default-interceptor-ref name="defaultStack"/>
如果不引用默认的拦截器(栈),struts2的很多功能都用不了。
Interceptor本质是一个Java类,新建一个Java类即可。有3种方式:
public interface Interceptor extends Serializable { void destroy(); void init(); String intercept(ActionInvocation var1) throws Exception; }
在init()中做初始化,在destroy中清理善后,intercept()是核心方法,用于拦截处理。
public class MyInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation actionInvocation) throws Exception { //去的时候做一些处理 System.out.println("before"); //放行 String result = actionInvocation.invoke(); //回来的时候做一些处理 System.out.println("after"); return result; } }
需要返回String,如果需要在回来的时候做一些处理,要将return放到最后。
public class MyInterceptor extends MethodFilterInterceptor { @Override protected String doIntercept(ActionInvocation actionInvocation) throws Exception { //去的时候做一些处理 System.out.println("before"); //放行 String result = actionInvocation.invoke(); //回来的时候做一些处理 System.out.println("after"); return result; } }
Action中有多个处理业务的方法:
public class MyAction{ public String add(){ System.out.println("add"); return "ok"; } public String update(){ System.out.println("update"); return "ok"; } public String delete(){ System.out.println("delete"); return "ok"; } }
拦截器配置:
<struts> <package name="action" namespace="/" extends="struts-default"> <interceptors> <interceptor name="myInterceptor" class="interceptor.MyInterceptor"> <param name="includeMethods">add,delete</param> </interceptor> </interceptors>
<action name="MyAction_*" class="action.MyAction" method="{1}"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="myInterceptor"></interceptor-ref> <result name="ok">/index.jsp</result> <allowed-methods>add,update,delete</allowed-methods> </action> </package> </struts>
MethodFilterInterceptor常与Action动态方法调用搭配使用。
注册拦截器时,需指定要拦截的方法|不拦截的方法:
<interceptor name="myInterceptor" class="interceptor.MyInterceptor">
<param name="includeMethods">add,delete</param>
<param name="excludeMethods">update</param>
</interceptor>
includeMethods指定此拦截器要拦截的方法,excludeMehtods指定不拦截的方法,这2个参数不能一起使用。指定了其中一个,剩下的方法都是另一个的。
要调用的方法是includeMethods中的方法时,才会使用此拦截器进行拦截,否则不使用此拦截器进行拦截。
此例中,访问MyAction_add、MyAcion_delete时,均会调用此拦截器;访问MyAction_update时,不会调用此拦截器。
处理机制:请求传递给此拦截器,此拦截器检查要调用的方法是否是includeMethods中的方法,是就处理,不是就直接放行。
用户登录,登录成功后可执行相关操作,直接执行用户操作,不再检查用户权限、信息,这是不行的。
比如用户可以直接在地址栏输入URL,转到操作页面进行操作,跳过用户登录。
可以使用拦截器拦截用户请求,检查用户权限:
从session中获取用户信息、权限,如果满足条件,就放行,如果未登录、权限不够,就转发到对应的登录页面、提示页面。
在用户登录成功时,将用户信息、权限放到session中。
可使用MethodFilterInterceptor只拦截Action中需要检查权限的某些方法。
原文:https://www.cnblogs.com/chy18883701161/p/11483245.html