2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【拦截器机制】

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【拦截器机制】

时间:2022-03-04 09:04:52

相关推荐

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【拦截器机制】

【Java EE (Struts2 + Spring + Hibernate)开发】:Struts2(二)之【拦截器机制】

本文地址:/shanglianlm/article/details/50096113

详解 Struts 2 的拦截器机制

1 拦截器在 Struts 2 中的作用

Struts 2 框架的绝大部分功能都是通过拦截器来实现的,当 StrutsPrepareAndExecuteFilter 拦截到用户请求后,大量拦截器将会对用户请求进行处理,然后才会调用用户开发的 Action 实例的方法来处理请求。

拦截器与 Action 之间的关系:

2 Struts 2 内建的拦截器

3 配置拦截器

定义拦截器

<!-- 通过指定拦截器名和拦截器实现类来定义拦截器 --><interceptor name="拦截器名" class="拦截器实现类" />

定义拦截器和参数

<!-- 通过指定拦截器名和拦截器实现类来定义拦截器 --><interceptor name="拦截器名" class="拦截器实现类" /><!-- 为拦截器指定参数值 --><param name="参数名">参数值</param></interceptor>

定义拦截器栈

<interceptor-stack name="拦截器栈名"><interceptor-ref name="拦截器一" /><interceptor-ref name="拦截器二" /></interceptor-stack>

拦截器栈里面也可以包含拦截器栈。

4 使用拦截器

在 Action 中使用拦截器,

<package name="lee" extends="struts-default"><!-- 应用所需使用的拦截器都在该元素下配置 --><interceptors><!-- 配置mysimple拦截器 --><interceptor name="mysimple"class="org.crazyit.app.interceptor.SimpleInterceptor"><!-- 为拦截器指定参数值 --><param name="name">简单拦截器</param></interceptor></interceptors><action name="loginPro" class="org.crazyit.app.action.LoginAction"><result name="error">/WEB-INF/content/error.jsp</result><result name="success">/WEB-INF/content/welcome.jsp</result> <!-- 配置系统的默认拦截器 --><interceptor-ref name="defaultStack"/><!-- 应用自定义的mysimple拦截器 --><interceptor-ref name="mysimple"><param name="name">改名后的拦截器</param></interceptor-ref></action><action name="*"><result>/WEB-INF/content/{1}.jsp</result></action></package>

5 配置默认拦截器

<package name="包名"><!-- 所有拦截器和拦截器栈都配置在该元素下 --><interceptors><!-- 定义拦截器 --><interceptor .../><!-- 定义拦截器栈 --><interceptor-stack ../></interceptors><!-- 配置该包下的默认拦截器 --><default-interceptor-ref name="拦截器名或拦截器栈名" />或者<default-interceptor-ref name="拦截器名或拦截器栈名" /><param name="参数名">参数值</param></default-interceptor-ref><action ../></package>

在 Struts 2 的 struts-default.xml 文件中有

<struts><package name="struts-default"><default-interceptor-ref name="defaultStack" /></package></struts>

当我们定义的包继承 struts-default 包时,则 defaultStack 拦截器栈会自动生效。

6 实现拦截器类

如果用户要开发自己的拦截器类,应该实现 com.opensymphony.xwork2.interceptor.Interceptor 接口,该接口的类定义如下:

public interface Interceptor extends Serializable{// 销毁该拦截器之前的回调方法void destroy();// 初始化该拦截器之前的回调方法void init(); // 拦截器实现拦截的逻辑方法String intercept(ActionInvocation invocation) throws Exception;}

public class SimpleInterceptor extends AbstractInterceptor{//简单拦截器的名字private String name;//为该简单拦截器设置名字的setter方法public void setName(String name){this.name = name;}public String intercept(ActionInvocation invocation)throws Exception{//取得被拦截的Action实例LoginAction action = (LoginAction)invocation.getAction();//打印执行开始的实现System.out.println(name + " 拦截器的动作---------" + "开始执行登录Action的时间为:" + new Date());//取得开始执行Action的时间long start = System.currentTimeMillis();//执行该拦截器的后一个拦截器//如果该拦截器后没有其他拦截器,则直接执行Action的execute方法String result = invocation.invoke();//打印执行结束的时间System.out.println(name + " 拦截器的动作---------" + "执行完登录Action的时间为:" + new Date());long end = System.currentTimeMillis();System.out.println(name + " 拦截器的动作---------" + "执行完该Action的事件为" + (end - start) + "毫秒");return result;}}

7 使用拦截器

使用拦截器步骤:

1. 通过

<struts><!-- 通过常量配置Struts 2的国际化资源信息 --><constant name="struts.custom.i18n.resources" value="mess"/><!-- 通过常量配置Struts 2所使用的解码集--><constant name="struts.i18n.encoding" value="GBK"/><!-- 配置本系统所使用的包 --><package name="lee" extends="struts-default"><!-- 应用所需使用的拦截器都在该元素下配置 --><interceptors><!-- 配置mysimple拦截器 --><interceptor name="mysimple"class="org.crazyit.app.interceptor.SimpleInterceptor"><!-- 为拦截器指定参数值 --><param name="name">简单拦截器</param></interceptor></interceptors><action name="loginPro" class="org.crazyit.app.action.LoginAction"><result name="error">/WEB-INF/content/error.jsp</result><result name="success">/WEB-INF/content/welcome.jsp</result> <!-- 配置系统的默认拦截器 --><interceptor-ref name="defaultStack"/><!-- 应用自定义的mysimple拦截器 --><interceptor-ref name="mysimple"><param name="name">改名后的拦截器</param></interceptor-ref></action><action name="*"><result>/WEB-INF/content/{1}.jsp</result></action></package></struts>

8 拦截方法的拦截器

//拦截方法的拦截器,应该继承MethodFilterInterceptor抽象类public class MyFilterInterceptorextends MethodFilterInterceptor{//简单拦截器的名字private String name;//为该简单拦截器设置名字的setter方法public void setName(String name){this.name = name;}//重写doIntercept方法,实现对Action的拦截逻辑public String doIntercept(ActionInvocation invocation)throws Exception{//取得被拦截的Action实例LoginAction action = (LoginAction)invocation.getAction();//打印执行开始的时间System.out.println(name + " 拦截器的动作---------"+ "开始执行登录Action的时间为:" + new Date());//取得开始执行Action的时间long start = System.currentTimeMillis();//执行该拦截器的后一个拦截器,或者直接指定Action的execute方法String result = invocation.invoke();//打印执行结束的时间System.out.println(name + " 拦截器的动作---------" + "执行完登录Action的时间为:" + new Date());long end = System.currentTimeMillis();//打印执行该Action所花费的时间System.out.println(name + " 拦截器的动作---------"+ "执行完该Action的事件为" + (end - start) + "毫秒");return result;}}

<struts><!-- 通过常量配置Struts 2的国际化资源信息 --><constant name="struts.custom.i18n.resources" value="mess"/><!-- 通过常量配置Struts 2所使用的解码集--><constant name="struts.i18n.encoding" value="GBK"/><!-- 配置本系统所使用的包 --><package name="lee" extends="struts-default"><!-- 应用所需使用的拦截器都在该元素下配置 --><interceptors><!-- 配置mysimple拦截器 --><interceptor name="mysimple"class="org.crazyit.app.interceptor.MyFilterInterceptor"><!-- 为拦截器指定参数值 --><param name="name">拦截方法的拦截器</param></interceptor></interceptors><action name="loginPro" class="org.crazyit.app.action.LoginAction"><result name="error">/WEB-INF/content/error.jsp</result><result name="success">/WEB-INF/content/welcome.jsp</result> <!-- 配置系统的默认拦截器 --><interceptor-ref name="defaultStack"/><!-- 应用自定义的mysimple拦截器 --><interceptor-ref name="mysimple"><!-- 重新指定name属性的属性值 --><param name="name">改名后的拦截方法过滤拦截器</param><!-- 指定execute方法不需要被拦截 --><param name="excludeMethods">execute</param></interceptor-ref></action><action name="*"><result>/WEB-INF/content/{1}.jsp</result></action></package></struts>

9 拦截器的执行顺序

<struts><!-- 通过常量配置Struts 2的国际化资源信息 --><constant name="struts.custom.i18n.resources" value="mess"/><!-- 通过常量配置Struts 2所使用的解码集--><constant name="struts.i18n.encoding" value="GBK"/><!-- 配置本系统所使用的包 --><package name="lee" extends="struts-default"><!-- 应用所需使用的拦截器都在该元素下配置 --><interceptors><!-- 配置mysimple拦截器 --><interceptor name="mysimple"class="org.crazyit.app.interceptor.SimpleInterceptor"><!-- 为拦截器指定参数值 --><param name="name">简单拦截器</param></interceptor></interceptors><action name="loginPro" class="org.crazyit.app.action.LoginAction"><result name="error">/WEB-INF/content/error.jsp</result><result name="success">/WEB-INF/content/welcome.jsp</result> <!-- 配置系统的默认拦截器 --><interceptor-ref name="defaultStack"/><!-- 应用自定义的mysimple拦截器 --><interceptor-ref name="mysimple"><param name="name">第一个</param></interceptor-ref><interceptor-ref name="mysimple"><param name="name">第二个</param></interceptor-ref></action><action name="*"><result>/WEB-INF/content/{1}.jsp</result></action></package></struts>

10 拦截结果的监听器

public class MyPreResultListener implements PreResultListener{//定义在处理Result之前的行为public void beforeResult(ActionInvocation invocation,String resultCode){//打印出执行结果System.out.println("返回的逻辑视图为:" + resultCode);try{invocation.invoke();}catch (Exception ex){ex.printStackTrace();}finally{}}}

手动注册给拦截器

public class BeforeResultInterceptorextends AbstractInterceptor{public String intercept(ActionInvocation invocation)throws Exception{//将一个拦截结果的监听器注册给该拦截器invocation.addPreResultListener(new MyPreResultListener()); System.out.println("execute方法执行之前的拦截...");//调用下一个拦截器,或者Action的执行方法String result = invocation.invoke();System.out.println("execute方法执行之后的拦截...");return result;}}

11 覆盖拦截器栈里特定拦截器的参数

<struts><!-- 通过常量配置Struts 2的国际化资源信息 --><constant name="struts.custom.i18n.resources" value="mess"/><!-- 通过常量配置Struts 2所使用的解码集--><constant name="struts.i18n.encoding" value="GBK"/><!-- 配置本系统所使用的包 --><package name="lee" extends="struts-default"><!-- 应用所需使用的拦截器都在该元素下配置 --><interceptors><!-- 配置mysimple拦截器 --><interceptor name="mysimple"class="org.crazyit.app.interceptor.SimpleInterceptor"><!-- 为拦截器指定参数值 --><param name="name">简单拦截器</param></interceptor><!-- 配置第二个拦截器 --><interceptor name="second" class="lee.SecondInterceptor"/><!-- 配置名为my-stack的拦截器栈 --><interceptor-stack name="my-stack"><!-- 配置拦截器栈内的第一个拦截器 --><interceptor-ref name="mysimple"><param name="name">第一个</param></interceptor-ref><!-- 配置拦截器栈内的第二个拦截器 --><interceptor-ref name="second"><param name="name">第二个</param></interceptor-ref></interceptor-stack></interceptors><action name="loginPro" class="org.crazyit.app.action.LoginAction"><result name="error">/WEB-INF/content/error.jsp</result><result name="success">/WEB-INF/content/welcome.jsp</result> <!-- 配置系统的默认拦截器 --><interceptor-ref name="defaultStack"/><!-- 应用上面的拦截器栈 --><interceptor-ref name="my-stack"><!-- 覆盖指定拦截器的指定参数值 --><param name="second.name">改名后的拦截器</param></interceptor-ref></action><action name="*"><result>/WEB-INF/content/{1}.jsp</result></action></package></struts>

12 使用拦截器完成权限控制

权限检查拦截器类:

//权限检查拦截器继承AbstractInterceptor类public class AuthorityInterceptorextends AbstractInterceptor{//拦截Action处理的拦截方法public String intercept(ActionInvocation invocation)throws Exception{//取得请求相关的ActionContext实例ActionContext ctx = invocation.getInvocationContext();Map session = ctx.getSession();//取出名为user的Session属性String user = (String)session.get("user");//如果没有登录,或者登录所用的用户名不是scott,都返回重新登录if (user != null && user.equals("") ){return invocation.invoke();}//没有登录,将服务器提示设置成一个HttpServletRequest属性ctx.put("tip" ,"您还没有登录,请输入,leegang登录系统");//直接返回login的逻辑视图return Action.LOGIN;}}

定义拦截器

<!-- 用户拦截器定义在该元素下 --><interceptors><!-- 定义了一个名为authority的拦截器 --><interceptor name="authority" class="org.crazyit.app.interceptor.AuthorityInterceptor"/></interceptors>

使用拦截器

<!-- 定义一个名为viewBook的Action,其实现类为ActionSupport --><action name="viewBook"><!-- 返回success视图名时,转入/WEB-INF/content/viewBook.jsp页面 --><result>/WEB-INF/content/viewBook.jsp</result><interceptor-ref name="defaultStack"/><!-- 应用自定义拦截器 --><interceptor-ref name="authority"/></action><action name="*"><result>/WEB-INF/content/{1}.jsp</result></action>

考虑到多个 Action 都需要跳转到 login 逻辑视图,故将 login 的结果映射定义为一个全局结果映射。

<!-- 定义全局Result --><global-results><!-- 当返回login视图名时,转入login.jsp页面 --><result name="login">/WEB-INF/content/login.jsp</result></global-results>

<interceptors><!-- --><interceptor name="authority" class="lee.AuthorityInterceptor" /><!-- --><interceptor-stack name="mydefault"><!-- --><interceptor name="default-stack" /><!-- --><interceptor name="authority" /></interceptor-stack></interceptors>

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。