1.struts2能完成数据的设置,数据的封装,数据的类型转换,数据的校验等等。struts2是如何来完成这些功能的?struts2的所有功能都是由拦截器来完成的。
2.拦截器是struts2的核心。拦截器是一个类似于过滤器的类。在执行action的处理方法前会 先执行拦截器,然后再执行action的处理方法,然后再执行拦截器,再响应。
3. struts2的所有功能都是由拦截器来实现的,而拦截器在struts2中时可以自由配置和自由装配的。所以struts2的所有功能也都是可插拔的。并且struts2中的拦截器是可以自定义的,所以如果struts2没有提供项目所需的功能时,可以通过自定义拦截器来实现。
4. struts2的拦截器有哪些,分别有什么功能:
5.struts2中拦截器定义的位置在struts-default.xml中
6.自定义拦截器步骤:
a) 编写类,实现Interceptor接口
public class ActionExecuteTimeInterceptor implements Interceptor{ @Override public void destroy() { } @Override public void init() { } @Override public String intercept(ActionInvocation invocation) throws Exception { long start=System.currentTimeMillis(); //执行下一个拦截器 如果下面没有拦截器则执行action的处理方法,并将结果返回 String result = invocation.invoke(); System.out.println("执行时间为:"+(System.currentTimeMillis()-start)); return result; } }
b) 在struts.xml中配置拦截器
<!-- 拦截器配置 --> <interceptors> <!-- 配置自定义拦截器 name 是唯一的 class 是自定义拦截器的完全限定名 --> <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor> </interceptors>
c) 在对应action中 引用自定义拦截器
<package name="default" extends="struts-default" namespace="/"> <!-- 拦截器配置 --> <interceptors> <!-- 配置自定义拦截器 name 是唯一的 class 是自定义拦截器的完全限定名 --> <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor> </interceptors> <action name="add" class="cn.sxt.action.UserAction" method="add"> <result>/success.jsp</result> <!-- 在action中引用自定义的拦截器 --> <interceptor-ref name="executeTime"></interceptor-ref> </action> </package>
7.自定义拦截器有两种方式实现,一种实现Interceptor接口还可以继承AbstractInterceptor类来实现:如:
public class HelloInterceptor extends AbstractInterceptor{ @Override public String intercept(ActionInvocation invocation) throws Exception { System.out.println("hello interceptor 被执行"); return invocation.invoke(); } }
8.如果引用了自定义拦截器,那么struts2的拦截器将不再起作用。如果需要使用struts2的拦截器需要手动引入。
<action name="add" class="cn.sxt.action.UserAction" method="add"> <result>/success.jsp</result> <!-- 在action中引用自定义的拦截器 --> <interceptor-ref name="executeTime"></interceptor-ref> <interceptor-ref name="helloInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </action>
9.当自定义拦截器比较多时,在action中引用拦截器将会变得比较麻烦,所以呢,struts2提供了拦截器栈。拦截器栈是用来引用已经定义好的拦截器的。一个拦截器栈可以包括多个拦截器,引用拦截器栈的方式和引用拦截器的方式一样。
<!-- 拦截器配置 --> <interceptors> <!-- 配置自定义拦截器 name 是唯一的 class 是自定义拦截器的完全限定名 --> <interceptor name="helloInterceptor" class="cn.sxt.interceptor.HelloInterceptor"></interceptor> <interceptor name="executeTime" class="cn.sxt.interceptor.ActionExecuteTimeInterceptor"></interceptor> <!-- 定义拦截器栈 --> <interceptor-stack name="myStack"> <interceptor-ref name="executeTime"></interceptor-ref> <interceptor-ref name="helloInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <action name="add" class="cn.sxt.action.UserAction" method="add"> <result>/success.jsp</result> <!-- 在action中引用自定义的拦截器 --> <interceptor-ref name="myStack"></interceptor-ref> </action>
10.在struts2如果没有自定义拦截器时,action类会引用默认的拦截器栈。如果有自定义拦截器后,想自定义拦截器设置为默认拦截器应该如何操作?
在package中去定义一个default-interceptor-ref即可。
<!-- 设置默认拦截器 --> <default-interceptor-ref name="myStack"></default-interceptor-ref> <action name="add" class="cn.sxt.action.UserAction" method="add"> <result>/success.jsp</result> </action>
11.拦截器的使用:
登录拦截器用来实现用户登录检查:
public class LoginInterceptor extends AbstractInterceptor{ @Override public String intercept(ActionInvocation invocation) throws Exception { //判断执行的Action是否login.action //如果不是 判断用户是否登录 //如果登录了 执行下一个拦截器,如果没有登录 去登录 //获取执行action的名称 String actionName=invocation.getProxy().getActionName(); if("login".equals(actionName)){ return invocation.invoke(); } Object obj=ServletActionContext.getRequest().getSession().getAttribute("currentUser"); if(obj!=null){ return invocation.invoke(); } return Action.LOGIN; } }
配置
<struts> <package name="default" extends="struts-default" namespace="/"> <!-- 拦截器配置 --> <interceptors> <interceptor name="loginInterceptor" class="cn.sxt.interceptor.LoginInterceptor"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="loginInterceptor"></interceptor-ref> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myStack"></default-interceptor-ref> <!-- 定义全局结果集 --> <global-results> <result name="login">/login.jsp</result> </global-results> <action name="login" class="cn.sxt.action.UserAction" method="login"> <result>/success.jsp</result> </action> <action name="show" class="cn.sxt.action.UserAction" method="show"> <result>/show.jsp</result> </action> </package> </struts>
12.总结:
拦截器是单列的,所有action执行的都是同一个拦截器。所以在自定义拦截器时要注意线程安全的问题。拦截器只拦截action。
13.注意过滤器和拦截器区别
14. 方法拦截器
方法拦截器是比拦截器更加细粒度的拦截器,只拦截方法。通过配置方法拦截器可以有效提高系统性能。
/** * 自定义方法拦截器 * */ public class AddMethodInterceptor extends MethodFilterInterceptor{ @Override protected String doIntercept(ActionInvocation invocation) throws Exception { System.out.println("进入方法拦截器"); return invocation.invoke(); } }
配置
<!-- 配置方法拦截器 --> <interceptor name="addInterceptor" class="cn.sxt.interceptor.AddMethodInterceptor"> <!-- 配置哪些方法 需要被拦截 --> <param name="includeMethods">add</param> <!-- 排除哪些方法不被拦截 <param name="excludeMethods"></param> --> </interceptor>
原文:https://www.cnblogs.com/Vincent-yuan/p/11154909.html