Spring MVC Handler拦截器用例
Spring MVC HandlerInterceptor Example
Spring HandlerInterceptor 与 Servlet 过滤器类似, Servlet 过滤器更强大些, 不过它只能在 web.xml 中配置( 正如对 DispatcherServlet 的配置一样, 译者注 ), 而 HandlerInterceptor 可通过 Spring 应用上下文 xml 文件和 Java 代码配置, HandlerInterceptor 可以用来避免重复的处理程序代码, 比如用作认证检测, 区域检查等不同用途.
在 Java 中, 我们可以重写 WebMvcConfigurerAdapter#addInterceptors( InterceptorRegistry ) 方法, 该回调方法在参数中提供了一个 InterceptorRegistry 对象,
使用 InterceptorRegistry#addInterceptor( HandlerInterceptor ) 方法可以向 Spring 注入 HandlerInterceptor 接口, 该接口有适配器 HandlerInterceptorAdapter.
InterceptorRegistry#addInterceptor( HandlerInterceptor ) 方法返回一个 InterceptorRegistration,允许您进一步配置已注册的拦截器,例如添加应该应用的URL模式。
HandlerInterceptor 接口有三个方法:
preHandle(): It is executed before actual handler is executed. 在实际处理之前执行, 返回值是布尔类型, false 取消处理
postHandle(): It is executed after handler is executed. 在实际处理之后执行
afterCompletion(): It is executed after the complete request is finished. 在完成请求后执行
import ...
@EnableMvc
@ComponetScan(basePackageClasses = { Index.class })
public final class MyWebAppInitializer extends WebConfigAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor( new HandlerInterceptorAdapter() {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true; // 继续处理
}
}).addPathPatterns("/*", "/*.jpg");
//
}
...
}
如果不调用 addPathPatterns( String... ) , 则会匹配所有 RequestMapping
Spring 过滤器用例
javax.servlet
Interface Filter
All Known Implementing Classes:
GenericFilter, HttpFilter
default void destroy()
//Called by the web container to indicate to a filter that it is being taken out of service.
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
//The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.
default void init(FilterConfig filterConfig)
//Called by the web container to indicate to a filter that it is being placed into service.
实现效果:
package club.init;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class StaticResourceFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
intercept((HttpServletRequest)request, (HttpServletResponse)response, chain);
}
public void intercept(HttpServletRequest request, HttpServletResponse response, FilterChain chain) {
// 添加服务器名
try {
response.addHeader("Server", "Fast Tomcat");
} catch (Exception e) {
e.printStackTrace();
}
// 获取 refer
Enumeration<String> headers = request.getHeaderNames();
String refer = null;
String content = "GET " + request.getRequestURI() + "
";
while (headers.hasMoreElements()) {
String header = headers.nextElement();
content += String.format("%s : %s
", header, request.getHeader(header));
if ("referer".equals(header)) {
refer = request.getHeader(header);
break;
}
}
Log.d(content);
if (request.getRequestURI().matches(".*\..+")) {
// 静态资源
if (refer == null || !refer.matches("https?://abc.com/.*")) {
response.setStatus(404);
response.addHeader("Error", "You can't use this resource without abc.com");
return;
}
response.addHeader("Content-Disposition",
String.format("attachment; filename*=UTF-8''%s", request.getRequestURI().replaceAll(".*/", "")));
}
try {
chain.doFilter(request, response);
} catch (IOException | ServletException e) {
e.printStackTrace();
}
}
}
最好使用 HttpFilter 这个类
这里有一个使用过滤器的项目: https://github.com/develon2015/Spring-filter