Struts2学习笔记四(拦截器与注解)

    xiaoxiao2025-06-26  8

    这是学习过程的一些记录,可能会有些地方出错,仅供参考

    拦截器的介绍

    在Webwork的中文文档的解释为——拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者在定义的action执行的前后加入执行的代码,也可以在一个action执行前阻止其执行。也就是说它提供了一种可以提取action中可重代码,统一管理和执行的方式。

    拦截器与Fliter过滤器的区别 过滤器是所有web开发都能够使用的技术,也就是说filter是web开发中的一种规范,但是拦截器Interceptor是Struts2的一门技术,只有在Struts2中可以使用。在过滤器中,filter能够过滤所有的资源,包括servlet、jsp、html等资源,但是因为拦截器是属于Struts2的技术,所以也就只能拦截Struts2所特有的资源,也就是Action,拦截器只对后缀为action的进行拦截。 拦截器的作用

    在Struts2中,拦截器可以说是Struts2的核心技术,我们之所以不用关心编码问题,参数封装问题,这都是因为拦截器都帮我们做好了,因此我们可以只专注于业务逻辑的处理,拦截器在内部还帮我们做了许多的事情。

    拦截器的定义与使用 创建拦截器类的两种方式 package com.wzm.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.Interceptor; /* * 拦截器的第一种创建方式,通过实现接口Interceptor,接口是属于拦截器的最底层,需要实现其中的所有方法 */ public class MyInterceptor implements Interceptor{ public String intercept(ActionInvocation invocation) throws Exception { System.out.println("Interceptor在action之前执行了"); //invocation.invoke()方法类似于过滤器Filter的放行chain //在处理完本拦截器的相应逻辑后,将请求交于下一个拦截器,如果没有就直接交于Action执行 //其返回值为Action执行完后的返回值,这个返回值最终要到struts.xml中与result标签对比 String str = invocation.invoke(); System.out.println(str); //在Action执行完之后,其返回值还会经过拦截器,可以再进行相应逻辑处理 System.out.println("Interceptor在action之后执行了"); //最终将action的返回值送到struts.xml的result中对比 return str; } public void destroy() { // TODO Auto-generated method stub } public void init() { // TODO Auto-generated method stub } } package com.wzm.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import com.opensymphony.xwork2.interceptor.Interceptor; /* * 拦截器的第一种创建方式,通过继承AbstractInterceptor,该类实现了Interceptor接口 * 该类只需要我们实现intercept方法 */ public class MyInterceptor1 extends AbstractInterceptor{ public String intercept(ActionInvocation invocation) throws Exception { System.out.println("Interceptor1在action之前执行了"); //invocation.invoke()方法类似于过滤器Filter的放行chain //在处理完本拦截器的相应逻辑后,将请求交于下一个拦截器,如果没有就直接交于Action执行 //其返回值为Action执行完后的返回值,这个返回值最终要到struts.xml中与result标签对比 String str = invocation.invoke(); System.out.println(str); //在Action执行完之后,其返回值还会经过拦截器,可以再进行相应逻辑处理 System.out.println("Interceptor1在action之后执行了"); //最终将action的返回值送到struts.xml的result中对比 return str; } } 拦截器的定义与使用 <package name="test7" extends="struts-default" namespace="/"> <!-- interceptors用来定义拦截器的 --> <interceptors> <!-- interceptor定义一个拦截器,name可以自己定,class为拦截器的全限定名 可以有多个 interceptor --> <interceptor name="myInterceptor" class="com.wzm.interceptor.MyInterceptor"></interceptor> <interceptor name="myInterceptor1" class="com.wzm.interceptor.MyInterceptor1"></interceptor> <!-- interceptor-stack定义一组拦截器,即将interceptor定义的拦截器包含进来 interceptor-stack可以在里边包含另一组拦截器 --> <interceptor-stack name="myInterceptorStack"> <!-- 这里需要包含进Struts2中默认的一组拦截器 因为struts2默认的拦截器会帮我们做很多事,例如模型驱动封装就是默认拦截器帮我们做的 如果不包含进来,当我们使用这组拦截器时就只会执行我们自己定义的拦截器 --> <interceptor-ref name="defaultStack"></interceptor-ref> <!-- 自己定义的拦截器 --> <interceptor-ref name="myInterceptor"></interceptor-ref> <interceptor-ref name="myInterceptor1"></interceptor-ref> </interceptor-stack> </interceptors> <!-- 定义好拦截器要使用,这里是在全局使用拦截器,即对整个包下的action有效 --> <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref> <action name="demo8" class="com.wzm.action.ActionDemo8"> <!-- 在action中使用拦截器,即该拦截器只在该action中生效 同时如果全局也有使用拦截器的话,全局的会失效,以action的优先 --> <interceptor-ref name="myInterceptor"></interceptor-ref> <result>/ognl.jsp</result> </action> </package> 对特定方法的拦截

    在之前的拦截器都是对action的所有方法进行拦截,这里实现对action的特定的方法进行拦截。

    创建拦截器 package com.wzm.interceptor; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor; /* * 在创建拦截器时,不管是实现接口Interceptor还是继承父类AbstractInterceptor, * 这两种方式都是对action中的所有方法都拦截,也就是说不过请求过来到action的哪个方法都会先执行拦截器 * 而这里的继承MethodFilterInterceptor类。 * 可以实现只对访问某些方法的请求进行拦截,这个底层同样是实现了Interceptor */ public class MyInterceptor2 extends MethodFilterInterceptor{ @Override protected String doIntercept(ActionInvocation invocation) throws Exception { System.out.println("MyInterceptor2在action之前执行了"); String string = invocation.invoke(); System.out.println("MyInterceptor2在action只会执行了"); return string; } } 拦截器的使用 <package name="test8" extends="struts-default" namespace="/"> <interceptors> <interceptor name="MyInterceptor2" class="com.wzm.interceptor.MyInterceptor2"> <!-- 在定义拦截器的时候,在内部添加标签param includeMethods代表要拦截访问哪些方法的请求 excludeMethods代表不拦截访问哪些方法的请求 方法可以写多个,用逗号隔开 <param name="includeMethods">find</param> --> <param name="excludeMethods">find</param> </interceptor> </interceptors> <action name="demo9" class="com.wzm.action.ActionDemo8" method="find"> <interceptor-ref name="MyInterceptor2"></interceptor-ref> </action> </package> Action类 package com.wzm.action; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.wzm.entity.User; public class ActionDemo8 extends ActionSupport implements ModelDriven<User>{ //注意,当action实现ModelDriven来封装一个对象时,ModelDriven会把被封装的对象也放在Root区的栈顶 private User user = new User(); public User getModel() { return user; } @Override public String execute() throws Exception { System.out.println("execute执行"); return null; } public String find() throws Exception { System.out.println("find执行"); return null; } }

    Struts2注解的使用

    在Struts2中同样有注解,通过使用注解可以代替struts.xml中的部分配置,要使用注解有两个条件。

    要导入一个struts2解压缩包lib下的包struts2-convention-plugin-2.3.24.jar注解只能在特定的包下使用,只有包名中包含action,actions,struts,struts2下的类才能使用注解。 注解的使用 package com.wzm.action; import org.apache.struts2.convention.annotation.Action; import org.apache.struts2.convention.annotation.Namespace; import org.apache.struts2.convention.annotation.ParentPackage; import org.apache.struts2.convention.annotation.Result; import com.opensymphony.xwork2.ActionSupport; /* * 注解的使用 */ /* * @ParentPackage要继承的包,@Namespace命名空间 * 相当于 * <package name="test8" extends="struts-default" namespace="/"> </package> */ @ParentPackage("struts-default") @Namespace("/") public class ActionDemo9 extends ActionSupport{ /* * value:访问路径 * results:返回的逻辑页面 * 相当于 * <action name="demo10" class="com.wzm.action.ActionDemo9" method="execute"> * <result name="success" type="dispatcher">/ognl.jsp</result> * <result name="login" type="redirect">/ognl.jsp</result> </action> */ @Action(value="demo10",results= { @Result(name="success",type="dispatcher",location="/ognl.jsp"), @Result(name="login",type="redirect",location="/ognl.jsp") }) @Override public String execute() throws Exception { System.out.println("execute执行"); return null; } }

    Struts2的工作流程

    当tomcat服务器启动,Struts2先加载好各种配置文件,当一个请求过来时,会被前端控制器所拦截,然后就进入到StrutsPrepareAndExecuteFilter中,在其中创建了ActionContext还有ValueStack和Action等对象,然后还创建了ActionMapper对象,通过ActionMapper判断请求资源是否为Action,如果不是就直接正常放行,如果是则会进入到核心程序进行拦截过滤,在核心程序内部会创建一个代理Action,ActionProxy内部会调用ActionInvocation的一个方法invoke,这个方法按顺序会调用拦截器,一个拦截器执行完毕又会调用invoke方法,如果还有拦截器就继续执行,如果没有就执行action,然后action执行完毕就返回一个字符串,这个字符串又会经过之前的所有拦截器到达struts.xml中,在其中与result的name匹配,最终跳转到一个逻辑页面。

    最新回复(0)