拦截器从字面意思来看就是限制,限制用户访问某些网页。在Action提出请求之前用拦截器来做权限设置,让符合的用户跳入相应的界面中。最近做的一个商城项目中就用到了自定义的拦截器,实现了一个简单的session判断,成功就登陆,不成功就跳转到门户。
Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现。AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
我的理解是每一个action请求都会在拦截器的内部,当发生请求的时候,Struts会找对应的配置文件,实例化相应的拦截器对象,如设置拦截器属性excludeMethods。很类似于过滤器的,但是过滤器的范围要大于拦截器。
第一种方法就是直接实现Interceptor接口,这样的话,有个弊端,这里面的init() destroy() intercept() 方法都需要实现了。
第二种方法是继承自AbstractInterceptor抽象类,实现了Interceptor接口,并且对里面的init()和destroy()方法进行空实现,而把intercept()方法设置为抽象方法,让继承它的子类去实现,这样的话,子类只要实现这个intercept()方法就可以了,比上面的简单。
第三种方法是继承自MethodFilterInterceptor(我下面就是用这个方法实现的),这个类叫做方法过滤拦截器,MethodFilterInterceptor继承自AbstractInterceptor,并且提供了一种机制,即可以指定对Action中某些方法进行拦截或者是不拦截,所谓拦截不拦截,指的就是拦截器中的intercept()方法是否被执行了,若没有执行,就是没有拦截,若执行了,就是拦截了。
总的来说,相比之前的接口和抽象类,最后一个只需要指定对Action中某些方法进行拦截是最简单的。是通过includeMethods和excludeMethods这两个参数来设置那个方法需要拦截的,在Struts.xml中进行配置。
1>首先我们要自定义一个拦截器类:
package cn.itcast.shop.interceptor; import org.apache.struts2.ServletActionContext; import cn.itcast.shop.adminuser.vo.AdminUser; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; /** * interceptor * @author Zhouzhou * @date 2016-1-25 * @time 下午09:48:21 */ /** * that class want to judge the session is null,it extends the class named : MethodFilterInterceptor, */ public class PrivilegeInterceptor extends MethodFilterInterceptor{ /** * the method doIntercept is the main method of the MethodFilterInterceptor */ @Override protected String doIntercept(ActionInvocation actionInvocation) throws Exception { //judge login // AdminUser adminUser = (AdminUser) ServletActionContext.getRequest() .getSession().getAttribute("existAdminUser"); if(adminUser != null){ // is logined ,have the userinfo in the session return actionInvocation.invoke(); }else{ // is not login ActionSupport support = (ActionSupport) actionInvocation.getAction(); support.addActionError("You are not logged in!No permission to access!"); return ActionSupport.LOGIN; } } }
2>然后在配置文件中去注册这个拦截器,并在后台登陆的action中利用excludeMethods这个成员变量来绑定login这个方法被拦截。
struts.xml <!-- Configure: registered place interceptor --> <interceptors> <interceptor name="privilegeInterceptor" class="cn.itcast.shop.interceptor.PrivilegeInterceptor"/> </interceptors> <!-- 后台登录Action --> <action name="adminUser_*" class="adminUserAction" method="{1}"> <result name="loginFail">/admin/index.jsp</result> <result name="loginSuccess" type="redirect">/admin/home.jsp</result> <interceptor-ref name="privilegeInterceptor"> <param name="excludeMethods">login</param> </interceptor-ref> <interceptor-ref name="defaultStack"/> </action>
3>然后是在login 这个方法被调用的时候,就去验证session是不是空的,来判断是否有这个用户名和密码的匹配,然后放入了session中。
/** * login method--azz */ public String login() { User existUser = userService.login(user); // use the username and pwd check the user is exist if (existUser == null) { //login fail this.addActionError("error,your user or pwd is error, please login again..."); return LOGIN; } else { // login success // set the user information into the session ServletActionContext.getRequest().getSession() .setAttribute("existUser", existUser); // goto the struts.xml ↓ //<result name="loginSuccess" type="redirect">/admin/home.jsp</result> return "loginSuccess"; } }
这样一来就轻松实现了用户登陆时候,session是否为空的判断了。
1.拦截器定义了一种机制,可以让开发定义一些代码在action执行之前&后执行。
2.提高了代码的复用,想想我们开发asp.net的时候总是写上if(session["username"]==null)之类的话在if(!Page。ispostback)里面。每个页面都有去判断session。在我们有了这个拦截器之后呢,我们只需要在每个action配置里面写上:
<interceptor-ref name="拦截器名称"/> <interceptor-ref name="defaultStack"/>
3.其中includeMethods和excludeMethods是来决定这个action里面的方法是否需要被拦截。