拦截器部分:
拦截器和 Servlet规范中的 Filter非常类似,不过 Filter的作用范围是整个HttpServletRequest的处理过程,而拦截器仅作用于Controller,不涉及到View的渲染,在大多数情况下,使用拦截器比Filter速度要快
拦截器是典型的责任链模式.
Interceptor接口:具体一个拦截器
voidintercept(Execution execution, InterceptorChain chain) throwsException;
InterceptorChain接口:拦截器链.
voiddoInterceptor(Execution execution) throwsException;
我们来看一个拦截器链实现:
InterceptorChainImpl类:
class InterceptorChainImpl implements InterceptorChain {
private final Interceptor[] interceptors;
private int index = 0;
private Object result = null;
InterceptorChainImpl(Interceptor[] interceptors) {
this.interceptors = interceptors;
}
Object getResult() {
return result;
}
public void doInterceptor(Execution execution) throws Exception {
//只有当做到最后一个拦截器的时候, 才真正执行结果
if(index==interceptors.length)
result = execution.execute();
else {
//其他的情况, 执行每个拦截器的动作, 并执行下一个.
// must update index first, otherwise will cause stack overflow:
index++;
interceptors[index-1].intercept(execution, this);
}
}
}
其他部分:
//这个filter用来代替DispatcherServlet来处理请求
//使用Filter的一个好处是如果 URL没有被任何 Controller的映射方法匹配到,
//则可以简单地调用FilterChain.doFilter()将 HTTP请求传递给下一个 Filter,
//这样,我们就不必自己处理静态文件,而由Web服务器提供的默认 Servlet处理,效率更高。
public class DispatcherFilter implements Filter {
private final Log log = LogFactory.getLog(getClass());
private Dispatcher dispatcher;
public void init(final FilterConfig filterConfig) throws ServletException {
log.info("Init DispatcherFilter...");
//初始化拦截器
this.dispatcher = new Dispatcher();
this.dispatcher.init(
new Config() {
public String getInitParameter(String name) {
return filterConfig.getInitParameter(name);
}
public ServletContext getServletContext() {
return filterConfig.getServletContext();
}
}
);
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
String method = httpReq.getMethod();
if ("GET".equals(method) || "POST".equals(method)) {
//dispatcher请求完成, 并完成渲染, 调用其他的filter
//如果这个filter放在第一位的话, 那么就已经完成渲染了, 可能后面的夜不会起作用吧?
if (!dispatcher.service(httpReq, httpResp))
chain.doFilter(req, resp);
return;
}
httpResp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
}
public void destroy() {
log.info("Destroy DispatcherFilter...");
this.dispatcher.destroy();
}
}
DispatcherServlet类:
这个类就是用来处理请求的转发器.必须映射成"/"
主要处理的类:
public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpResp = (HttpServletResponse) resp;
String method = httpReq.getMethod();
if ("GET".equals(method) || "POST".equals(method)) {
//如果没有找到匹配的, 那么就使用静态处理器去处理
//否则的话, 使用匹配的action去处理
if (!dispatcher.service(httpReq, httpResp))
staticFileHandler.handle(httpReq, httpResp);
return;
}
//其他情况: 不支持其他类型的请求
httpResp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
}
浙公网安备 33010602011771号