实现拦截器——编写自己的拦截器(上篇)
(Interceptor)拦截器在Struts2中有着至关重要的作用,Struts2本身定 义了丰富的拦截器,但作为一个框架(Framework)扩展性也是不可 缺 少的,Struts2为了提高自身的灵活性允许我们自己创建拦截器, 而 且自定义拦截器的创建过程相当容易.
实现接口Interceptor
在Struts2中要编写自己的拦截器需要实现Xwork框架中的一个简单接口:Interceptor
[com.opensymphony.xwork2.interceptor.Interceptor],这个接口只规定了3个方法.
public interface Interceptor extends Serializable {
void destroy();
void init();
String intercept(ActionInvocation invocation) throws Exception;
}
在这个接口中 destroy 和 init 方法分别执行清理和初始化工作,intercept方法执行拦截器的主要工作.
继承AbstractInterceptor
当我们不需要让拦截器执行清理和初始化工作时,Struts2还提供了一个选择AbstractInterceptor[com.opensymphony.xwork2.interceptor.AbstractInterceptor].这是一个抽象类,并实现了Interceptor接口,只是重写了destroy 和 init 方法,在方法中没有执行任何操作.
public abstract class AbstractInterceptor implements Interceptor {
public void init() {
}
public void destroy() {
}
public abstract String intercept(ActionInvocation invocation) throws Exception;
}
编写自己的拦截器
在上面我们提到了编写自定义拦截器的方式,拦截器直接或间接的实现Interceptor接口.现在让我们来自己写一个来了解一下.下面例子演示日志拦截器的实现,拦截器做的工作是拦截到请求后获得请求IP和请求URL 然后在磁盘上创建文件记录下IP和URL并记录请求时间,OK我们开始吧.
package lele.struts2.interceptor;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class LoggerInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
LoggerService logger = DefaultLoggerService.getInstance();
HttpServletRequest request=ServletActionContext.getRequest();
String ip=request.getRemoteAddr();
String url=request.getRequestURL().toString();
logger.createLog(ip,url);
return invocation.invoke();
}
}
以上代码在intercept 方法中获得了IP地址和URL,然后将IP和URL作为参数传到了createLog方法中来创建日志.中途考虑到文件的操作问题单独把文件操作封装成单个实例服务,代码如下:
package lele.struts2.interceptor;
public interface LoggerService {
public void createLog(String ip,String url);
}
然后用默认的日志服务类来实现具体文件操作,代码如下:
public class DefaultLoggerService implements LoggerService {
private static DefaultLoggerService instance;
private BufferedWriter bw=null;
public static DefaultLoggerService getInstance() {
if (instance == null) {
instance = new DefaultLoggerService();
}
return instance;
}
private DefaultLoggerService() {
}
@Override
public void createLog(String ip, String url) {
synchronized (this) {
String filename = "e:/log/request.log";
File f = new File(filename);
try {
bw = new BufferedWriter(new FileWriter(f, true));
StringBuilder sb = new StringBuilder();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
sb.append(sdf.format(new Date()));
sb.append(" ");
sb.append( ip );
sb.append(" ");
sb.append( url );
sb.append("(");
sb.append(this);
sb.append(")");
bw.write(sb.toString());
bw.newLine();
} catch (Exception ex) {
throw new RuntimeException(ex);
} finally {
this.closeFile();
}
}
}
public void closeFile(){
try{
if(bw!=null)
bw.close();
}catch(Exception ex){
throw new RuntimeException(ex);
}
}
}
OK,一个日志拦截器就做好了(至于拦截器的配置我就不多说了,配置问题可以看我的上篇文章).注意编写拦截器时一定要求拦截器是无状态的,因为在Struts2中并不保证每个请求都会创建单独的拦截器实例,如果拦截器带有状态则容易引发并发问题.
拦截器是Struts2中比较重要的一个功能,很好的理解拦截器可以帮助自己编写复用性很高的代码.
就和大家聊到这了,希望能对Struts2中的拦截器有所理解.下面章节会和大家聊到Struts2中的几个比较重要的拦截器,也是比较实用的一些,然后再自己来做一个拦截器,并引出Struts2拦截器编程中应注意的一些问题.
我的联系方式:
MSN: wang4717@live.cn
QQ: 471776739
Mail: wanglehappy9112@gmail.com