疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

struts2 interceptor拦截器学习


 

        struts2的拦截器与Servlet的Filter过滤器相似,但是也有不同。拦截器主要处理的是action类,在action类执行前对其进行处理,常用的地方有权限管理,登录状态检查等,如果某个功能需要在几乎所有action中完成,也可以抽出来放在拦截器中进行,这就是所谓的AOP,面向切面编程吧。filter过滤器主要是处理servlet,jsp,html等。过滤器是基于回调的方式实现的。拦截器只能对action请求起作用,而过滤器可以对几乎所有的请求起作用。
 
        现在介绍具体的拦截器的使用方法。
 
       首先创建com.cike.ssns.action.authority包,再创建UserAuthCodeInterceptor.java类。
 
public class UserAuthCodeInterceptor extends AbstractInterceptor{
 
    private UserService userService;
    
    public UserService getUserService() {
        return userService;
    }
 
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
 
    @Override
    public String intercept(ActionInvocation arg0) throws Exception {
        // TODO Auto-generated method stub
        ActionContext ac = arg0.getInvocationContext();
        Map<String,Object> map = ac.getParameters();
        if(map.get("userId") != null && map.get("authCode") != null){
            String[] userId = (String[])map.get("userId");
            String[] authCode = (String[])map.get("authCode");
            if(!userService.isUserLogin(authCode[0], Integer.valueOf(userId[0]))){
                ac.put("json", ResponseFactory.errorResponse(ErrorCode.Service.USER_NOT_LOGIN));
                return "error";
            }
            return arg0.invoke();
        }
        else{
            ac.put("json", ResponseFactory.errorResponse(ErrorCode.Service.PARSER_MISSING));
            return "error";
        }
    }
 
}
       解释上面的类:ActionInvocation是action的调度类,通过该调度类可以获得该action的上下文,如下:
 
ActionContext ac = arg0.getInvocationContext();
通过该上下文ac,我们可以获得访问该action使用的request,并获取该requrest里面的参数(也就是我们在url中传入的参数),如下:
 
Map<String,Object> map = ac.getParameters();
       arg0.invoke() 即设置拦截器结束时调用并进入action,一般是返回成功值。如果不调用invoke(),则不会正常进入action,而是直接让action返回拦截器的返回值。这么说比较抽象,我们看例子比较容易明白。如果我们没有调用invoke(),直接return “error”,并且在上下文中加入“json”-〉“****”键值对,我们在前台看到的struts返回是“****”。这里的“error”是我们在struts.xml中设置的result。因为我们在struts.xml中设置的返回值是json,所以对于每个action,struts会自动返回action中的json变量。我们在上下文中加入该键值对的原因就是这个。
 
         为了在拦截器中使用spring托管的UserService类,必须把该拦截器也发配给spring托管。在applicaContext.xml中加入该bean。
 
在struts.xml中配置:
 
   1:          <interceptors>
   2:              <interceptor name="userAuthCode" class="UserAuthCode"></interceptor>
   3:              <interceptor-stack name="userAuthCodeStack">
   4:                  <interceptor-ref name="userAuthCode"></interceptor-ref>
   5:                  <interceptor-ref name="defaultStack"></interceptor-ref>
   6:              </interceptor-stack>
   7:          </interceptors>
在每个struts.xml的每个action中添加<interceptor-ref name="userAuthCodeStack"></interceptor-ref>如下:
 
   1:          <action name="findUser" class="FindUserAction">
   2:              <result name="success">/result.jsp</result>
   3:              <result name="error">/result.jsp</result>
   4:              <interceptor-ref name="userAuthCodeStack"></interceptor-ref>
   5:          </action>
用浏览器打开findUser这个用例,通过断点可以知道,在调用action前会先调用拦截器。如果参数中的authCode出错,则不会进入action,直接返回错误代码。