开发者学堂课程【Java Web开发系列课程 - Struts2框架入门:拦截器配置详解】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/537/detail/7316
拦截器配置详解
内容介绍:
一、课程回顾
二、拦截器配置的注意事项
一、课程回顾
拦截器案例中包括以下3个步骤:
1.定义拦截器
包括两种定义方式,可以任意选择其一,,其中最重要的在于invocation.invoke()
,该方法会使得系统执行下一操作,而在过滤器中也是相似的,一旦被拦截或过滤,就无法继续向下执行,而进行该方法的调用,即可继续向下执行下一步操作。
public class TimeInterceptor extends AbstractInterceptor {
@Override
public string intercept (ActionInvocation invocation) throws
Exception
long start =System.currentTimeMillis();
String result =invocation.invoke();
//返回结果类型为 string,且方法为 invocation.invoke
long end =System.currentTimeMillis();
System.out.println("执行 action 所用时间为:"+(end-start)+"ms");
return result;
}
}
2. 配置拦截器
在 struts.xml 中配置拦截器:
<struts>
<package name=”default”extends=”struts-default”
namespace=”/”>
<interceptors>
<interceptor name=”time”class=”cn.sxt.interceptor.
TimeInterceptor”>
</interceptors>
3. 引用拦截器
<action name=”hello”class=”cn.sxt.interceptor.HelloAc
tion”>
<result>/index.jsp</result>
<interceptor-ref name=”time”/>
</action>
<package>
</struts>
当请求 hello.action 时即会执行该拦截器。
上节所学的配置拦截器功能相关的内容十分有限,而拦截器的配置本身却十分复杂,因此上节课所学内容无法满足实际的应用需求,本节课我们会具体学习拦截器的配置。
二、拦截器配置的注意事项
在 HelloAction 中写入一个私有的 string 类型的属性 name:
package cn.sxt.action;
import com.opensymphony.xwork2.Action;
public class HelloAction {
private String name;
public string execute ( ) {
System.out.println("execute");
return Action.SUCCESS;
}
}
在“ return Action.SUCCESS;}”
下方,单击选择 Generate Getters
and Setters 生成其 Getters and Setters 生成方法,在弹出的页面中
选择 Select all,并将 Insertion point 设置为 After ‘execute’ (即
将执行方法放在前方,将生成方法放在后方,如此编码一目了然,而
不是混作一团,导致重点(执行方法和属性)不明,读码困难。
因此,最终的配置代码如下:
package cn.sxt.action;
import com.opensymphony.xwork2.Action;
public class HelloAction {
private String name;
public string execute ( ) {
System.out.println("name:"+name);
return Action.SUCCESS;
}
public string getName ( ) {
return name;
}
public void setName (String name ) {
this.name=name;
}
}
此时即可运行代码。
注:若还要写入 age、list 等属性,为了代码的美观、易读,一般建
议写在执行代码部分。
在请求 action 时,想要向其传输一个参数 name 为“张三疯”
即在搜索框中输入
localhost:8080/interceptor/helloaction?nam
e=张三疯,执行请求,输出结果为“This is my JSP page”
,说明请求成功,返回后 console 界面显示“name=null 执行该 Action 所用时间为:56ms”。
可以发现此时 name 没有相应的值,据此我们可以得出配置拦截器的注意事项。
1. 当引用了自定拦截器时,默认的拦截器将不起作用。
Struts 的所有功能都是通过拦截器来实现的,而我们之前在定义 action 时,并没有特定去引用拦截器,而拦截器能够运行便归功于默认拦截器的存在。
在 struts-default.xml
中,配置了默认拦截器,在配置了默认拦截器后,若不引用拦截器,默认拦截器将会起作用。
根本原因在于struts-default.xml中含有这样一段代码<default-interceptor-ref name=”defaultStack”/>
,即引用名为 defaultStack的默认拦截器,而defaultStack 是由多个拦截器组成的栈,因此,struts-default.xml 中实际引用了包含多个拦截器在内的拦截器栈。
2. 当引用自定义拦截器后,若要使用 struts2提供的拦截器功能,需要手动引用。
则完整代码如下:
<struts>
<package name=”default”extends=”struts-default”
namespace=”/”>
<!--配置拦截器-->
<interceptors>
<interceptor name=”time”class=”cn.sxt.interceptor.
TimeInterceptor”>
</interceptors>
<action name=”hello”class=”cn.sxt.interceptor.HelloAc
tion”>
<result>/index.jsp</result>
<!--引用拦截器-->
<interceptor-ref name=”time”/>
<!--引用默认的拦截器栈:引用拦截器和拦截器栈的方式相同-->
<interceptor-ref name=”defaultStack”/>
</action>
<package>
</struts>
之所以可以自定义拦截器,还是因为该拦截器继承了 struts-default,故只要再次手动引用 struts-default 中的拦截器栈 defaultStack 即可。
保存后,重新启动,再次运行,返回后显示“name:张三疯 执行该 Action 所用时间为:81ms”。
相对于手动引用之前,此时成功向 name 传输了值“张三疯”,且此时执行 Action 的时间相对较长,这是因为其执行过程中又多经过了许多拦截器。
3.当 action 应用的拦截器个数较多时,可以将多个拦截器放入一个拦截器栈中,即需要定义一个新的拦截器栈。
如上面的手动引用拦截器的过程,虽然可以通过手动引用执行自定义拦截器,但引用拦截器时,需要两次引用,编程代码相对复杂,则此时可以定义一个新的拦截器栈,定义拦截器栈的代码如下:
<!--一个拦截器栈中可以包含多个拦截器的引用:拦截器栈与拦截器的引用方法相同-->
<interceptor-stack name=”mystack”>
<!--引用拦截器-->
<interceptor-ref name=”time”/>
<!--引用默认的拦截器栈:引用拦截器和拦截器栈的方式相同-->
<interceptor-ref name=”defaultStack”/>
</interceptor-stack>
则简化后的完整代码如下:
<struts>
<package name=”default”extends=”struts-default”
namespace=”/”>
<interceptors>
<interceptor name=”time”class=”cn.sxt.interceptor.
TimeInterceptor”>
<interceptor-stack name=”mystack”>
<interceptor-ref name=”time”/>
<interceptor-ref name=”defaultStack”/>
</interceptor-stack>
</interceptors>
<action name=”hello”class=”cn.sxt.interceptor.HelloAc
tion”>
<result>/index.jsp</result>
<interceptor-ref name=”myStack”/>
</action>
<package>
</struts>
此处通过定义一个新的拦截器栈 myStack,将原本的拦截器 time 和拦截器栈defaultStack 同时囊括了进去。如此,在面临需引用多个拦截器或拦截器栈时,可通过定义一个新的拦截器栈的方式来简化代码的编写。
保存后重新启动,运行结果显示“name:张三疯 执行该 Action 所用时间为89ms”,说明代码编写无误,运行顺畅。
4.当自定义的拦截器栈被包下的所有 action 使用时,可以定义为默认拦截器栈或默认拦截器。
在 struts-default.xml 中有如下代码:<default-interceptor-ref name=”defaultStack”/>,
那么我们在自定义默认拦截器(栈)时也可以采取与之相同的方式,但在实际编写过程中应着重注意其位置。则通过定义默认拦截器(栈)的代码编写如下:
<struts>
<package name=”default”extends=”struts-default”
namespace=”/”>
<interceptors>
<interceptor name=”time”class=”cn.sxt.interceptor.
TimeInterceptor”>
<interceptor-stack name=”mystack”>
<interceptor-ref name=”time”/>
<interceptor-ref name=”defaultStack”/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name=”myStack”/>
<action name=”hello”class=”cn.sxt.interceptor.Hello
Action”>
<result>/index.jsp</result>
</action>
<package>
</struts>
查询地址为“http://struts.apache.org/dtds-2.3.dtd”的文件,显示包的定义顺序为package(result-types?,interceptors?,default-stack-ref?,default-action-ref?,default-class-ref?,global-results?,global-exception-mappings?,action*),即 default-stack-ref 直接放在 interceptors 后,而不可以放在 action 后。
故先前的代码编写无误。此时无需再引用拦截器(栈)。
保存后运行结果显示“name:张三疯 执行该 Action 所用时间为111ms”,说明定义默认拦截器设置成功。