技术分析之Struts2的拦截器技术
1. 拦截器的概述
* 拦截器的作用:对Action类中的方法进行拦截,进行程序的编写。
* 拦截器就是AOP(Aspect-Oriented Programming)的一种实现。(AOP是指用于在某个方法或字段被访问之前,进行拦截然后在之前或之后加入某些操作。)
* 过滤器:过滤从客服端发送到服务器端请求的
* 拦截器:拦截对目标Action中的某些方法进行拦截
* 拦截器不能拦截JSP
* 拦截到Action中某些方法
2. 拦截器和过滤器的区别
1)拦截器是基于JAVA反射机制的(拦截器配置的都是类的全路径),而过滤器是基于函数回调的(过滤器实例是由Tomcat服务器来创建的)
2)过滤器依赖于Servlet容器,而拦截器不依赖于Servlet容器
3)拦截器只能对Action请求起作用(Action中的方法),而过滤器可以对几乎所有的请求起作用(CSS JSP JS)
* 拦截器 采用 责任链 模式
> 在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链
> 责任链每一个节点,都可以继续调用下一个节点,也可以阻止流程继续执行
技术分析之自定义拦截器和配置
1. 编写拦截器,需要实现Interceptor接口,实现接口中的三个方法
public class OrderInterceptor extends AbstractInterceptor{
private static final long serialVersionUID = 3168450442031605321L;
/**
* 拦截的方法
*/
public String intercept(ActionInvocation ai) throws Exception {
// 输出
System.out.println("拦截器执行了22...");
// 让下一个拦截器去执行,不要忘记加 return
return ai.invoke();
}
}
2. 需要在struts.xml中进行拦截器的配置,配置一共有两种方式
<!-- 定义了拦截器 第一种方式 -->
<interceptors>
<interceptor name="orderInterceptor" class="com.itheima.demo4.OrderInterceptor"/>
</interceptors>
<!-- 演示拦截器 -->
<action name="order_*" class="com.itheima.demo4.OrderAction" method="{1}">
<!-- 引入拦截器,只要是引入自定义的拦截器,那么默认栈的拦截器就不执行了
<interceptor-ref name="orderInterceptor"/>
-->
<!-- 手动引入默认栈的拦截器
<interceptor-ref name="defaultStack"/>
-->
</action>
<!-- 第二种配置方式:定义拦截器栈 -->
<interceptors>
<interceptor name="orderInterceptor" class="com.itheima.demo4.OrderInterceptor"/>
<!-- 自定义拦截器栈 -->
<interceptor-stack name="mystack">
<interceptor-ref name="orderInterceptor"/>
<interceptor-ref name="defaultStack"/>
</interceptor-stack>
</interceptors>
<!-- 演示拦截器 -->
<action name="order_*" class="com.itheima.demo4.OrderAction" method="{1}">
<!-- 引入自定义拦截器栈 -->
<interceptor-ref name="mystack"/>
</action>
拦截器案例
1. 完成了登录的功能
2. 添加拦截器的功能(判断用户是否已经登录)
* 编写UserInterceptor拦截器,重写intercept方法,在该方法中判断用户是否已经登录,代码如下:
// 先获取到session,获取对象
User user = (User) ServletActionContext.getRequest().getSession().getAttribute("existUser");
if(user == null){
// 获取到目标的Action的对象
ActionSupport action = (ActionSupport) actionInvocation.getAction();
action.addActionError("大哥,你得需要登录啊!!");
// 没有登录
return "login";
}
// 执行下一个拦截器
return actionInvocation.invoke();
* 配置拦截器
* 注册拦截器
<interceptors>
<interceptor name="userInterceptor" class="com.itheima.interceptor.UserInterceptor"/>
</interceptors>
* 在CustomerAction中引入拦截器(注意:不要再UserAction中引入拦截器,默认会对UserAction的login方法进行拦截,从而不能登陆成功)
<interceptor-ref name="userInterceptor"/>
<interceptor-ref name="defaultStack"/>
3. login.jsp页面存在的问题
* 如果拦截器拦截成功了,会跳转到登录页面,登录成功后会默认在当前的窗口中显示。
* 需要设置在父窗口中显示:设置如下:
* <FORM id=form1 name=form1 action="${ pageContext.request.contextPath }/user_login.action" method=post target="_parent">
Struts2框架的标签库
OGNL表达式的特殊的符号
1. # 符号的用法:作用从context值栈中获取值,构建Map集合。
* 获得context中的数据
> <s:property value="#request.name"/>
> <s:property value="#session.name"/>
> <s:property value="#application.name"/>
> <s:property value="#attr.name"/>
> <s:property value="#parameters.id"/>
> <s:property value="#parameters.name"/>
* 构建一个map集合
* 例如:
* <s:radio name="sex" list="{'男','女'}"></s:radio>
* <s:radio name="sex" list="#{'0':'男','1':'女'}"></s:radio>
2. % 符号的用法:把字符串强制解析成OGNL的表达式
* 强制字符串解析成OGNL表达式。
> 例如:在request域中存入值,然后在文本框(<s:textfield>)中取值,现在到value上。
> <s:textfield value="%{#request.msg}"/>
3. $ 符号的用法:在配置文件中(XML或者properties)使用$获取值栈中的值
* 在配置文件中可以使用OGNL表达式,例如:文件下载的配置文件。
<action name="download1" class="cn.itcast.demo2.DownloadAction">
<result name="success" type="stream">
<param name="contentType">${contentType}</param>
<param name="contentDisposition">attachment;filename=${downFilename}</param>
</result>
</action>
Struts2框架标签库的概述