JAVA Struts2 DAY05
1 拦截器HelloWorld
1.1 问题
写一个拦截器的HelloWorld程序。
1.2 方案
拦截器的使用步骤
- 创建拦截器组件,实现接口Interceptor
- 在struts.xml中注册拦截器
- 在action的配置中引用拦截器
这里我们复用StrutsDay04项目的修改客户功能,并对打开修改页面的action引用自定义的拦截器。
1.3 步骤
步骤一:创建拦截器
创建包interceptor,在该包下创建拦截器组件FirstInterceptor,并实现接口Interceptor,在拦截方法中调用action业务方法,并且在调用action前后分别输出一些内容,以模拟对action请求的拦截。代码如下:
- package interceptor;
- import com.opensymphony.xwork2.ActionInvocation;
- import com.opensymphony.xwork2.interceptor.Interceptor;
- /**
- * 第一个拦截器
- */
- public class FirstInterceptor implements Interceptor {
- @Override
- public void destroy() {
- }
- @Override
- public void init() {
- }
- @Override
- public String intercept(ActionInvocationai) throws Exception {
- System.out.println("FirstInterceptor拦截前...");
- // 执行action业务方法
- ai.invoke();
- System.out.println("FirstInterceptor拦截后...");
- /*
- * 返回值匹配对应的result,但是一旦代码中调用了
- * ai.invoke时,则此返回值无效,Struts2会根据
- * action的返回值匹配result。如果当前代码中没有
- * 调用ai.invoke,则此返回值生效。
- * */
- return "error";
- }
- }
步骤二:注册拦截器
在struts.xml中,客户package下注册拦截器组件FirstInterceptor,代码如下:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
- "http://struts.apache.org/dtds/struts-2.1.7.dtd">
- <struts>
- <!--客户配置信息 -->
- <package name="customer"
- namespace="/customer" extends="struts-default">
- <interceptors>
- <!--注册拦截器 -->
- <interceptor name="first"
- class="interceptor.FirstInterceptor"/>
- </interceptors>
-
- <!--打开修改页面 -->
- <action name="toUpdateCustomer"
- class="action.ToUpdateCustomerAction">
- <result name="success">
- /WEB-INF/customer/update_customer.jsp
- </result>
- </action>
- </package>
- </struts>
步骤三:引用拦截器
在修改客户action的配置下,引用已注册的拦截器,代码如下:
- <?xmlversion="1.0"encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
- "http://struts.apache.org/dtds/struts-2.1.7.dtd">
- <struts>
- <!--客户配置信息 -->
- <package name="customer"
- namespace="/customer" extends="struts-default">
- <interceptors>
- <!--注册拦截器 -->
- <interceptor name="first"
- class="interceptor.FirstInterceptor"/>
- </interceptors>
-
- <!--打开修改页面 -->
- <action name="toUpdateCustomer"
- class="action.ToUpdateCustomerAction">
- <!--引用拦截器 -->
- <interceptor-ref name="first"/>
- <result name="success">
- /WEB-INF/customer/update_customer.jsp
- </result>
- </action>
- </package>
- </struts>
步骤四:测试
为了便于观察拦截器与Action的执行顺序,在Action的构造方法及业务方法中,输出一些内容,代码如下:
- package action;
- importjava.util.List;
- importdao.CustomerDAO;
- importentity.City;
- importentity.Customer;
- importentity.Sex;
- public class ToUpdateCustomerAction {
- // output
- private Customer customer; // 客户
- private List<Sex> sexes; // 性别
- private List<City> cities; // 城市
- publicToUpdateCustomerAction() {
- System.out.println("实例化ToUpdateCustomerAction...");
- }
-
- public String execute() {
- System.out.println("调用ToUpdateCustomerAction业务方法...");
-
- CustomerDAOdao = new CustomerDAO();
- // 模拟查询客户
- customer = dao.findById();
- // 模拟查询全部的性别
- sexes = dao.findAllSex();
- // 模拟查询全部的城市
- cities = dao.findAllCities();
- return "success";
- }
- public Customer getCustomer() {
- return customer;
- }
- public void setCustomer(Customer customer) {
- this.customer = customer;
- }
- public List<Sex>getSexes() {
- return sexes;
- }
- public void setSexes(List<Sex> sexes) {
- this.sexes = sexes;
- }
- public List<City>getCities() {
- return cities;
- }
- public void setCities(List<City> cities) {
- this.cities = cities;
- }
- }
重新部署并重启tomcat,然后重新访问修改客户页面,控制台输出结果如下图:
图-1
从输出结果中可以看出,拦截器是在实例化Action之后,调用业务方法之前开始调用的。
1.4 完整代码
本案例的完整代码如下所示:
FirstInterceptor完整代码
ToUpdateCustomerAction完整代码:
struts.xml完整代码:
2 扩展拦截器HelloWorld
2.1 问题
扩展拦截器HelloWorld示例,练习使用拦截器栈,并观察多个拦截器的执行顺序。
2.2 方案
创建一个新的拦截器,与第一个拦截器打包成栈,然后让修改客户的action引用这个拦截器栈,并观察控制台中这两个拦截器与Action的执行顺序。
2.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建一个新的拦截器
创建一个新的拦截器组件SecondInterceptor,代码如下:
- package interceptor;
- import com.opensymphony.xwork2.ActionInvocation;
- import com.opensymphony.xwork2.interceptor.Interceptor;
- /**
- * 第二个拦截器
- */
- public class SecondInterceptor implements Interceptor {
- @Override
- public void destroy() {
- }
- @Override
- public void init() {
- }
- @Override
- public String intercept(ActionInvocationai) throws Exception {
- System.out.println("SecondInterceptor拦截前...");
- ai.invoke();
- System.out.println("SecondInterceptor拦截后...");
- return "error";
- }
- }
步骤二:注册新拦截器,并打包成栈
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
- "http://struts.apache.org/dtds/struts-2.1.7.dtd">
- <struts>
- <!--客户配置信息 -->
- <package name="customer"
- namespace="/customer" extends="struts-default">
- <interceptors>
- <!--注册拦截器 -->
- <interceptor name="first"
- class="interceptor.FirstInterceptor"/>
- <interceptor name="second"
- class="interceptor.SecondInterceptor"/>
- <!--注册拦截器栈 -->
- <interceptor-stack name="myStack">
- <interceptor-ref name="first"/>
- <interceptor-ref name="second"/>
- </interceptor-stack>
- </interceptors>
-
- <!--打开修改页面 -->
- <action name="toUpdateCustomer"
- class="action.ToUpdateCustomerAction">
- <!--引用拦截器 -->
- <interceptor-ref name="first"/>
- <result name="success">
- /WEB-INF/customer/update_customer.jsp
- </result>
- </action>
- </package>
- </struts>
步骤三:引用拦截器栈
可以在action的配置下引用拦截器,也可以给一个包下所有的action统一设置默认使用的拦截器,代码如下:
- <?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
- "http://struts.apache.org/dtds/struts-2.1.7.dtd">
- <struts>
- <!--客户配置信息 -->
- <package name="customer"
- namespace="/customer" extends="struts-default">
- <interceptors>
- <!--注册拦截器 -->
- <interceptor name="first"
- class="interceptor.FirstInterceptor"/>
- <interceptor name="second"
- class="interceptor.SecondInterceptor"/>
- <!--注册拦截器栈 -->
- <interceptor-stack name="myStack">
- <interceptor-ref name="first"/>
- <interceptor-ref name="second"/>
- </interceptor-stack>
- </interceptors>
- <!--设置当前包下所有Action默认引用的拦截器 -->
- <default-interceptor-ref name="myStack"/>
-
- <!--打开修改页面 -->
- <action name="toUpdateCustomer"
- class="action.ToUpdateCustomerAction">
- <!--引用拦截器 -->
- <!--<interceptor-ref name="first"/> -->
- <result name="success">
- /WEB-INF/customer/update_customer.jsp
- </result>
- </action>
- </package>
- </struts>
步骤四:测试
重新部署项目并重启tomcat,重新访问修改客户页面时,控制台输出结果如下图:
图-2
从图中可以看出,多个拦截器拦截Action的顺序满足先进后出的原则,其顺序可以按照下图来理解和记忆:
图-3