前面讲述的所有示例工程的配置文件struts.xml中的package都继承了struts-default这个包。下面打开struts-default.xml这个文件,可以看到里面的主要内容有一下几种:
上面是struts-default.xml这个包里定义一些拦截器和拦截器栈。拦截器栈里面引用了一系列的拦截器,使用拦截器栈的时候请求会依次被拦截器中的各个拦截器拦截。
我们这里也可以定义自己的拦截器。
1.新建工程:SecondLearnStruts2Chap03
2.新建处理类HelloAction:
package com.test.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloAction extends ActionSupport{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String execute() throws Exception {
System.out.println("执行了HelloAction的默认方法");
return SUCCESS;
}
}
3.新建一个com.test.interceptor包,并在这个包里新建一个MyInterceptor拦截器:
package com.test.interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor{
@Override
public void destroy() {
// 拦截器销毁时调用
System.out.println("MyInterceptor销毁");
}
@Override
public void init() {
// 拦截器初始化时调用
System.out.println("MyInterceptor初始化");
}
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// 拦截器处理逻辑
System.out.println("在action执行之前");
String result = invocation.invoke();
System.out.println("result="+result);
System.out.println("在action执行之后");
return result;
}
}
这里要强调的是:新建的拦截器必须实现Interceptor这个接口以及实现里面定义的三个函数。其中destory函数在拦截器销毁时调用,init在拦截器初始化的时候调用。intercept方法在拦截到用户请求的时候调用。intercept方法中的核心就是invocation.invoke这句,这句代码的意思是执行用户请求的函数,其返回值就是我们的action中返回的值。
4.配置struts.xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="manage" namespace="/" extends="struts-default">
<interceptors>
<interceptor name="myInterceptor" class="com.test.interceptor.MyInterceptor"></interceptor>
</interceptors>
<action name="hello" class="com.test.action.HelloAction">
<result name="success" type="dispatcher">success.jsp</result>
<interceptor-ref name="myInterceptor"></interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
其中:使用<interceptors>标签定义了我们自己定义的拦截器,这里只是定义了这个拦截器,并没有使用。然后在action标签中通过<interceptor-ref>标签来使用我们自定义的拦截器。程序运行的时候通过配置文件找到了我们自定义的拦截器,默认就不会再执行系统默认的拦截器了,所以这里还要手动的通过
<interceptor-ref name="defaultStack"></interceptor-ref>
这句代码来使工程使用自带的拦截器。
上面的配置中,如果返回的是success就跳转到success.jsp文件。
5.定义success.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
Name:${name }
</body>
</html>
6.运行程序:
这里看一下控制台输出:
重点说一下程序的执行过程:
1.浏览器中发出请求,请求hello并带了参数值name;
2.请求被拦截器拦截,这里我们使用了自定义的拦截器以及默认的拦截器栈。
2.1首先被我们自定义的拦截器拦截,打印出“在action执行之前”;
2.1执行invocation.invoke方法,也就是执行响应用户请求的方法,这里是执行execute方法。这个方法中先进入默认拦截器;
2.2默认拦截器先执行set方法给处理类中的变量赋值,接着执行execute方法;
2.3执行完execute方法之后,跳转到success.jsp页面。这个页面要对变量取值,默认拦截器执行get方法;
2.4默认拦截器执行结束,进入到自定义拦截器。此时invocation.invoke执行结束。执行后面的代码,打印“在action执行之后”