1、什么是拦截器
在AOP中用于在某个方法或字段被访问之前,进行拦截然后加入某些操作,用于动态拦截Action调用的对象,提供了一种机制可以使开发者自定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可重用的部分的方式。
2、拦截器的实现原理
拦截器方法都是通过代理的方式来调用的,当请求到达Struts2的ServletDispatcher时,Struts2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。Struts2拦截器是可插拔的,拦截器是AOP的一种实现,Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链,在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。
3、自定义拦截器
代码示例
Demo1Action.java
package cn.ctgu.interceptor;
import com.opensymphony.xwork2.ActionSupport;
public class Demo1Action extends ActionSupport{
public String add() throws Exception {
// TODO Auto-generated method stub
System.out.println("Demo1Action add");
return SUCCESS;
}
public String delete() throws Exception {
// TODO Auto-generated method stub
System.out.println("Demo1Action delete");
return SUCCESS;
}
public String update() throws Exception {
// TODO Auto-generated method stub
System.out.println("Demo1Action update");
return SUCCESS;
}
public String find() throws Exception {
// TODO Auto-generated method stub
System.out.println("Demo1Action find");
return SUCCESS;
}
}
MyInterceptor.java
package cn.ctgu.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
//拦截器:第一种创建方式
//拦截器生命周期:随项目的启动而创建,随项目的关闭而销毁
public class MyInterceptor implements Interceptor{
//初始化方法
@Override
public void init() {
// TODO Auto-generated method stub
}
//拦截方法
@Override
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
return null;
}
//销毁方法
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
MyInterceptor2.java
package cn.ctgu.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.Interceptor;
//拦截器:第二种创建方式
//拦截器生命周期:随项目的启动而创建,随项目的关闭而销毁
//帮我们空实现了init和destroy方法,如果不需要实现这两个方法,就可以只实现intercept方法
public class MyInterceptor2 extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation arg0) throws Exception {
// TODO Auto-generated method stub
return null;
}
}
MyInterceptor3.java
package cn.ctgu.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.interceptor.Interceptor;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
//拦截器:第三种创建方式 MethodFilterInterceptor方法过滤拦截器
//功能:定制拦截器拦截的方法
//定制哪些方法需要拦截
//定制哪些方法不需要拦截
public class MyInterceptor3 extends MethodFilterInterceptor{
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
//前处理
System.out.println("MyInterceptor3的前处理!");
//放行
invocation.invoke();
//后处理
System.out.println("MyInterceptor3的后处理!");
return "success";//不放行就直接跳转,不执行后续的拦截器以及Action,直接交给Result处理结果,进行页面跳转
}
}
struts.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!--常量配置方式二 -->
<!--i18n:国际化,解决post提交乱码-->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- 指定访问action时的后缀名为.do或空
http://localhost:8080/struts2_1/hello/HelloAction.do
-->
<constant name="struts.action.extension" value="do,,"></constant>
<!-- 指定struts2是否以开发模式运行
1、热加载主配置文件(不需要重启即可生效)
2、提供更多错误信息输出,方便开发时调试
-->
<constant name="struts.devMode" value="false"></constant>
<!-- package:将Action配置封装,就是可以在Package中配置很多action
name属性:给包起个名字,起到标识作用,随便起,不能与其他包名重复
namespace属性:给action的访问路径中定义一个命名空间
extends属性:继承一个指定包
abstract属性:包是否为抽象的,标识属性,标识该包不能独立运行,专门呢被继承
-->
<package name="interceptor" namespace="/" extends="struts-default">
<!--配置拦截器 -->
<interceptors>
<!-- 1、注册拦截器 -->
<interceptor name="myInter3" class="cn.ctgu.interceptor.MyInterceptor3"/>
<!-- 2、注册拦截器栈 -->
<interceptor-stack name="myStack">
<!--自定义拦截器引入(建议放在20个拦截器之前) -->
<interceptor-ref name="myInter3">
<!--指定哪些方法不拦截 -->
<param name="excludeMethods">add,delete</param>
<!--指定哪些方法拦截
<param name="includeMethods">add,delete</param> -->
</interceptor-ref>
<!--引用默认的拦截器栈(20个) -->
<interceptor-ref name="defaultStack"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 3、指定包中的默认拦截器栈 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<action name="Demo1Action_*" class="cn.ctgu.interceptor.Demo1Action" method="{1}">
<!--为Action单独指定走哪个拦截器(栈)
<interceptor-ref name="myStack"></interceptor-ref> -->
<result name="success" type="dispatcher">/show1.jsp</result>
</action>
</package>
<package name="tag" namespace="/" extends="struts-default">
<action name="Demo2Action" class="cn.ctgu.tag.Demo2Action" method="execute">
<result name="success" type="dispatcher">/tag1.jsp</result>
</action>
</package>
</struts>
核心配置文件web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>Struts2_2</display-name>
<!-- 配置常量方法三 -->
<!-- <context-param>
<param-name>struts.i18n.encoding</param-name>
<param-value>utf-8</param-value>
</context-param> -->
<!-- struts2核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
4、Struts2标签
Demo2Action.java
package cn.ctgu.tag;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class Demo2Action extends ActionSupport{
public String execute() {
List<String>list=new ArrayList<>();
list.add("tom");
list.add("jerry");
list.add("rose");
list.add("jack");
ActionContext.getContext().put("list", list);
return SUCCESS;
}
}
tag1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--遍历标签iterator 方式一-->
<s:iterator value="#list"><!--OGNL表达式取出context中的值 -->
<s:property/><!-- 默认从栈顶元素开始取 --><hr/>
</s:iterator>
<!-----------------------------------><hr/>
<s:iterator value="#list" var="name">
<s:property value="#name"/><hr/>
</s:iterator>
<!-----------------------------------><hr/>
<s:iterator begin="1" end="100" step="1">
<s:property/>| <!--结果:打印从1到100 -->
</s:iterator>
<!-----------------------------------><hr/>
<s:if test="#list.size()==4">
list长度为4!
</s:if>
<s:elseif test="#list.size()==3">
list长度为3!
</s:elseif>
<s:else>
list不3不4!
</s:else>
<!----------------property配合ognl表达式取值-------------------><hr/>
<s:property value="#list.size()"/>
<s:property value="#session.user.name"/>
<!------------struts2表单标签-----------------------><hr/>
<!--好处1:内置了一套样式 -->
<s:form action="Demo2Action" namespace="/">
<s:textfield name="name" label="用户名"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>