读书人

struts2.X心得9-struts2自定义拦截器以

发布时间: 2013-03-06 16:20:31 作者: rapoo

struts2.X心得9--struts2自定义拦截器以及文件上传等几个拦截器使用案例

1.自定义拦截器

要使用自定义拦截器,就要编写自定义拦截器类,该类需要实现com.opensymphony.xwork2.interceptor.Interceptor接口。

因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defaultStack,这样应用才可以使用struts2框架提供的众多功能。

如果希望包下的所有action都使用自定义的拦截器,可以通过<default-interceptor-ref name=“permissionStack”/>把拦截器定义为默认拦截器。注意:每个包只能指定一个默认拦截器。另外,一旦我们为该包中的某个action显式指定了某个拦截器,则默认拦截器不会起作用。

2. 拦截器

假设有一种场景:

在action的一个方法中,要进行权限的控制。如果是admin用户登入,就执行该方法,如果不是admin用户登入,就不能执行该方法。

AccessAction

public String testAccess(){

if(this.username.equals("admin")){

//执行业务逻辑方法

return SUCCESS;

}else{

//不执行

return "failed";

}

}

2.1实现方案一

说明:

这样做程序的结构不是很好。原因是权限的判断和业务逻辑的方法紧密耦合在了一起。如果权限的判断很复杂或者是业务逻辑很复杂会造成后期维护的非常困难。所以结构不是很好

这种形式只能控制一个action中的一个方法。如果很多action中的很多方法都需要这种控制。会导致大量的重复代码的编写。

2.2实现方案二

动态代理可以实现。请参见cn.itcast.struts.jdkproxy包下的类。

2.3实现方案三

在struts2中,用拦截器(interceptor)完美的实现了这一需求。在struts2中,内置了很多拦截器,在struts-default.xml文件中可以看出。用户还可以自定义自己的拦截器。自定义拦截器需要以下几点:

在配置文件中:包括两个部分:声明拦截器栈和使用拦截器栈

struts-interceptor.xml

<!--

声明拦截器

-->

<interceptors>

<!--

定义自己的拦截器

-->

<interceptor name="accessInterceptor"

class="cn.itcast.struts2.action.interceptor.PrivilegeInterceptor">

</interceptor>

<!--

声明拦截器栈

-->

<interceptor-stack name="accessInterceptorStack">

<!--

引用自定义的拦截器

-->

<interceptor-ref name="accessInterceptor"></interceptor-ref>

<!--

引用struts2内部的拦截器栈

-->

<interceptor-ref name="defaultStack"></interceptor-ref>

</interceptor-stack>

</interceptors>

说明:红色部分是struts2内部的拦截器。可以从struts-default.xml文件中得到内容。自己定义的栈必须引入struts2默认的栈。因为我们在访问action时,属性的赋值等一些工作都是由内部的栈完成的。如果不写,struts2的功能将发挥不出来。可以用debug进行调试也能得出结论。

<!--

使用拦截器

-->

<default-interceptor-ref name="accessInterceptorStack"></default-interceptor-ref>

说明:使用拦截器栈。从上面声明部分可以看出,accessInterceptorStack栈既包括了自定义的拦截器,又包括了struts2内部的拦截器栈。


在拦截器类中,一个类如果是拦截器,必须实现Interceptor接口。

public class PrivilegeInterceptor implements Interceptor{

public void destroy() {

// TODO Auto-generated method stub

}

public void init() {

// TODO Auto-generated method stub

}

public String intercept(ActionInvocation invocation) throws Exception {

// TODO Auto-generated method stub

System.out.println("aaaa");

//得到当前正在访问的action

System.out.println(invocation.getAction().toString());

//得到Ognl值栈

System.out.println(invocation.getInvocationContext().getValueStack());

//请求路径action的名称,包括方法

System.out.println(invocation.getProxy().getActionName());

//方法名称

System.out.println(invocation.getProxy().getMethod());

//命名空间

System.out.println(invocation.getProxy().getNamespace());

String method = invocation.invoke();

return null;

}

}

说明:

1、 这个类中init、intercept和destroy三个方法说明了一个拦截器的生命周期。

2、 在interceptor方法中的参数invocation是执行action的上下文,可以从

这里得到正在访问的action、Ognl值栈、请求路径、方法名称、命名空间

等信息。以帮助程序员在拦截器中做相应的处理工作。

3、 红色部分是关键部分,就是调用action的方法。这里可以成为目标类的

目标方法。

4、因为这里配置的拦截器是针对包的,所以只要是包的action都起作用。


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>

<actionname="*_*"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-refname="PermissionInterceptor"/>

<interceptor-refname="defaultStack"></interceptor-ref>

</interceptor-stack>

</interceptors>

<actionname="*_*"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-refname="PermissionInterceptor"/>

<!-- sutruts默认的拦截器比如加上,否则像set注入等操作不能用 -->

<interceptor-refname="defaultStack"></interceptor-ref>

</interceptor-stack>

</interceptors>

<!-- 配置缺省的拦截器栈为自定义的拦截器栈,一定要写这个值,否则自定义的拦截器就没用了-->

<default-interceptor-ref name="myStack"/>

注意事项:

这三种拦截器的配置共同点就是都要配置默认的拦截器,必须写的<interceptor-refname="defaultStack"></interceptor-ref>;

不同点上面已经说明了,就是作用的范围不一样,可以根据实际开发选择不同的配置方法。

4.拦截器在文件上传中的应用

Struts配置文件中添加的配置:

<interceptor-refname="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>

读书人网 >编程

热点推荐