實現
html
implements javax.servlet.Filter、XML中配置filter信息。java
重寫init、doFilter、destroy三個方法web
void init(FilterConfig var1) throws ServletException
:初始化Filter,在servlet容器啓動時執行且只在此時啓動一次。(後續 不過濾指定請求 會用到)spring
void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException
:實現過濾功能,能夠在請求前預處理,也能夠請求後處理,分界線是chain.doFilter()
。spring-mvc
void destroy()
:用於Filter銷燬前,可用於資源回收。bash
使用session
public class TestFilter implements Filter {
private String excluded;
private String[] excludedPages;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
excluded = filterConfig.getInitParameter("excluded");
//System.out.println(excluded);
if (excluded!=null && excluded.length()>0){
excludedPages = excluded.split(",");
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
boolean flag = false;
for (String page : excludedPages){
if (httpServletRequest.getRequestURI().equals(page)){
flag = true;
}
}
if (flag){
filterChain.doFilter(servletRequest, servletResponse);
}else {
HttpSession session = httpServletRequest.getSession();
Object curUser = session.getAttribute("curUser");
if (curUser==null){
httpServletResponse.sendRedirect("/user/login");
}else {
filterChain.doFilter(servletRequest, servletResponse);
}
}
}
@Override
public void destroy() {
}
}
複製代碼
實現mvc
implements org.springframework.web.servlet.HandlerInterceptor
、spring-mvc.xml配置app
重寫3個方法框架
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
:若是返回true,則繼續後續Interceptor的preHandle方法和controller;若是返回false,則後面的都不會執行。void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception
:若是preHandle返回false,這個方法不會執行。該方法執行在preHandle以後,視圖渲染以前。多個Interceptor的postHandle的執行順序,是:先聲明的後執行。void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception
:該方法執行前提也是preHandle返回true。執行在請求結束以後,也就是渲染了視圖以後才執行,可用於資源清理。相似於Filter的destroy。使用
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("member");
if (user==null){
response.sendRedirect("/user/login");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
複製代碼
對比 | 攔截器 | 過濾器 |
---|---|---|
處理的目標 | 全部web請求 | Action-部分web請求 |
實現原理 | 函數回調 | Java反射(動態代理) |
應用場景 | 字符編碼 | 攔截未登陸用戶 |
URL級別的權限訪問 | 審計日誌 | |
過濾敏感詞 | ||
壓縮響應信息 | ||
執行順序 | 根據filter-mapping配置的前後 | 按配置的順序,可經過order控制 |
規範 | 在Servlet規範中定義,servlet容器支持 | spring容器內,spring框架支持 |
使用範圍 | 只能用於Web程序 | 不只Web程序,Application、swing均可以。 |
深度 | 只能在servlet先後使用 | 能夠深刻到方法先後,拋出異常先後。 |
Filter使用更加方便,Interceptor功能能夠更細緻的處理需求。
舉例:計算請求響應時間。
Filter:
```
void doFilter() throw Exception{
long time = System.currentTimeMillis();
chain.doFilter();
System.out.println("請求時間爲:"+ (System.currentTimeMillis()-time));
}
```
複製代碼
interceptor:
```
long time = System.currentTimeMillis();
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
time = System.currentTimeMillis();
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
System.out.println("Interceptor cost="+(System.currentTimeMillis()-start));
}
```
複製代碼
Interceptor須要一個提早聲明全局變量來存值,這就有可能引發線程問題。能夠經過TreadLocal解決。
相關