拦截器是Struts2的核心组件,Struts2的绝大部分功能都是通过拦截器来实现的,所以Struts2的很多功能都够建在拦截器的基础上。
Struts2拦截器的基础知识
拦截器实现了面向切面编程(AOP)的设计思想,拦截是AOP的一种实现策略。
AOP是目前软件开发中的一个热点,也是spring框架中的一项重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使业务逻辑各个部分之间的耦合度降低,提高程序的可重用性,同时提高开发的效率。
Struts2拦截器实现类
有些与项目业务逻辑相关的通用功能可以通过自定义拦截器来实现,而自定义拦截器需要实现Struts2提供的Interceptor接口,通过实现该接口可以开发拦截器类。该接口的代码如下:
import com.opensymphony.xwork2.ActionInvocation;
import java.io.Serializable;
public interface Interceptor extends Serializable{
void destory();
void init();
String intercept (ActionInvocation invocation) throws Exception;
}
该接口提供了3个方法:
(1)、destory()方法:与init()方法对应,用于在拦截器执行完之后释放init()方法里打开的资源。
(2)、init():有拦截器在执行之前调用,只要用于初始化系统资源,如打开数据库资源等。
(3)、intercept (ActionInvocation invocation)方法:该方法时拦截器的核心方法,实现具体的拦截操作,返回一个字符串作为逻辑视图。与Action一样,如果拦截器能够成功调用Action,则Action中的execute()方法返回一个字符串类型值,将其作为逻辑视图返回,否则,返回开发者自定义的逻辑视图。
而在java语言中,有时候通过一个抽象类来实现一个接口,在抽象类中提供该接口的空实现。这样在编写类的时候,可以直接继承该抽象类,不用实现那些不需要的方法。Struts2框架也提供了一个抽象拦截器类(AbstractInterceptor),该类对init()和destory()方法进行空实现,因为很多时候实现拦截器都不需要申请资源。AbstractInterceptor类的代码如下:
import com.opensymphony.xwork2.ActionInvocation;
public abstract class AbstractInterceptor implements Interceptor{
public void init(){
}
public void destory(){
}
public abstract String intercept(ActionInvocation invocation) throws Exception;
}
我们来举一个网上论坛过滤系统
文件框架:
news.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>评论</title>
</head>
<body>
请发表你的评论!
<hr>
<s:form action="public" method="post">
<s:textfield name="title" label="评论标题" />
<s:textarea name="content" cols="36" rows="6" label="评论内容"></s:textarea>
<s:submit value="提交" />
</s:form>
</body>
</html>
success.jsp:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>评论成功</title>
</head>
<body>
评论如下:
<hr>
评论标题:<s:property value="title"/>
<br>
评论内容:<s:property value="content" />
</body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaeee/web-app_3_1.xsd"
id="WebApp_ID"
version="3.1" >
<filter>
<!-- 配置Struts2核心控制器的名字 -->
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<!-- Struts2控制器的名字 -->
<filter-name>struts2</filter-name>
<!-- 拦截所有的URL请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>news.jsp</welcome-file>
</welcome-file-list>
</web-app>
struts.xml:
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<package name="I18N" extends="struts-default">
<!-- Struts2规定,对拦截器的配置应该在Action的配置之前 -->
<interceptors>
<!-- 文字过滤拦截器配置,replace是拦截器的名称 -->
<interceptor name="replace" class="interceptor.MyInterceptor"></interceptor>
</interceptors>
<!-- 文字过滤Action的配置 -->
<action name="public" class="interceptor.PublicAction">
<result name="success" >/interceptor/success.jsp</result>
<result name="login" >/interceptor/success.jsp</result>
<!-- Struts2系统默认拦截器 -->
<interceptor-ref name="defaultStack" />
<!-- 使用自定义拦截器 -->
<interceptor-ref name="replace"></interceptor-ref>
</action>
</package>
</struts>
MyInterceptor.java:
package interceptor;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyInterceptor extends AbstractInterceptor{
public String intercept(ActionInvocation ai) throws Exception{
//获取action实例
Object object=ai.getAction();
if(object!=null) {
//instanceof是拦截的意思,判断这个实例是不是被PublicAction拦截
if(object instanceof PublicAction) {
PublicAction ac=(PublicAction)object;
//获取用户提交的评论内容
String content=ac.getContent();
//判断用户提交的评论内容是否需要过滤的内容
if(content.contains("讨厌")) {
//以“喜欢”代替“讨厌”
content=content.replaceAll("讨厌", "喜欢");
//把代替后的内容设置为Action的评论内容
ac.setContent(content);
}
//对象不空,继续执行
//继续执行后面的操作,invoke()是Method类代表
return ai.invoke();
}
else {
//返回Action中的LOGIN逻辑视图字符串
return Action.LOGIN;
}
}
return Action.LOGIN;
}
}
PublicAction.java:
package interceptor;
import com.opensymphony.xwork2.ActionSupport;
public class PublicAction extends ActionSupport{
private String title;
private String content;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String execute() {
return SUCCESS;
}
}
运行结果:
评论:
显示评论页面: