1. 自定义拦截器
要使用自定义拦截器,就要编写自定义拦截器类,该类需要实现com.opensymphony.xwork2.interceptor.Interceptor接口。
因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。
如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-ref name=“permissionStack”/>把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。
2. 拦截器
假设有一种场景:
在action的一个方法中,要进行权限的控制。如果是admin用户登入,就执行该方法,如果不是admin用户登入,就不能执行该方法。
|
说明:
这样做程序的结构不是很好。原因是权限的判断和业务逻辑的方法紧密耦合在了一起。如果权限的判断很复杂或者是业务逻辑很复杂会造成后期维护的非常困难。所以结构不是很好
这种形式只能控制一个action中的一个方法。如果很多action中的很多方法都需要这种控制。会导致大量的重复代码的编写。
2.2 实现方案二
动态代理可以实现。请参见cn.itcast.struts.jdkproxy包下的类。
2.3 实现方案三
在struts2中,用拦截器(interceptor)完美的实现了这一需求。在struts2中,内置了很多拦截器,在struts-default.xml文件中可以看出。用户还可以自定义自己的拦截器。自定义拦截器需要以下几点:
在配置文件中:包括两个部分:声明拦截器栈和使用拦截器栈
|
在拦截器类中,一个类如果是拦截器,必须实现Interceptor接口。
|
3. 拦截器案例注意的地方
3.1中文乱码处理
public String delete() throws UnsupportedEncodingException{
//因为用的是struts2标签的url标签传过来的是url请求就是默认是get传过来的,所以要进行乱码处理
System.out.println(new String(URLDecoder.decode(msg).getBytes("ISO-8859-1"),"utf-8")+"==================");
return SUCCESS;
}
3.2 自定义拦截器注意事项,再次强调自定义拦截器类实现Interceptor接口
public String intercept(ActionInvocation invocation) throws Exception {
String result = "input";
//输出action
System.out.println(invocation.getAction());
//通过获取代理,然后获取action的名字
String ai = invocation.getProxy().getActionName();
System.out.println(ai);
if("UserAction_login".equals(ai)){
System.out.println("login执行了");
//invocation.invoke()是最关键的一步,执行目标类的目标方法
return invocation.invoke();
}else{
// 判断用户是否存在
ActionContext actionContext = ActionContext.getContext();
//获取用户对象
User user = (User) actionContext.getSession().get("user");
if(user != null){
System.out.println("delete执行了");
result = invocation.invoke();
return result;
}else{
System.out.println("用户没有登陆,不能够执行操作");
return "input";
}
}
3.3 三种struts.xml配置文件中的拦截器编写注册
第一种:自定义拦截器,适合拦截某一个特定的action中的特定的方法
<!-- 声明拦截器,拦截器要在global-results全局标签之前 -->
<interceptors>
<interceptor name="PermissionInterceptor"
class="www.csdn.interceptor.PermissionInterceptor"/>
</interceptors>
<action name="*_*" class="www.csdn.action.{1}"method="{2}">
<interceptor-ref name="PermissionInterceptor"/>
<interceptor-ref name="defaultStack"/>
<result name="success">/sc.jsp</result>
</action>
第二种:自定义拦截器栈,适合拦截某一个action中的所有方法
<interceptors>
<interceptor name="PermissionInterceptor"
class="www.csdn.interceptor.PermissionInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="PermissionInterceptor" />
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<action name="*_*" class="www.csdn.action.{1}"method="{2}">
<interceptor-ref name="myStack"/>
<result name="success">/sc.jsp</result>
</action>
3.第三种:定义全局的拦截器栈,适合拦截所有action
<!-- 声明拦截器,拦截器要在global-results全局标签之前 -->
<interceptors>
<interceptor name="PermissionInterceptor"
class="www.csdn.interceptor.PermissionInterceptor"/>
<interceptor-stack name="myStack">
<interceptor-ref name="PermissionInterceptor" />
<!-- sutruts默认的拦截器比如加上,否则像set注入等操作不能用 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 配置缺省的拦截器栈为自定义的拦截器栈,一定要写这个值,否则自定义的拦截器就没用了-->
<default-interceptor-ref name="myStack"/>
注意事项:
这三种拦截器的配置共同点就是都要配置默认的拦截器,必须写的<interceptor-ref name="defaultStack"></interceptor-ref>;
不同点上面已经说明了,就是作用的范围不一样,可以根据实际开发选择不同的配置方法。
4.拦截器在文件上传中的应用
Struts配置文件中添加的配置:
<interceptor-ref name="fileUpload">
<!-- 上传文件的类型 -->
<param name="allowedTypes">application/x-zip-compressed,
image/jpeg,image/pjpeg,image/gif,text/plain</param>
<!-- 上传文件的大小 -->
<param name="maximumSize">5242880</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>