過(guò)濾器和攔截器是Java Web中非常重要的組件,它們可以幫助我們?cè)赪eb應(yīng)用程序中執(zhí)行各種任務(wù),如對(duì)請(qǐng)求進(jìn)行驗(yàn)證、修改請(qǐng)求和響應(yīng)等。
首先我們來(lái)看看過(guò)濾器。過(guò)濾器是一種可以攔截http請(qǐng)求和響應(yīng)的組件,用于在Web應(yīng)用程序中運(yùn)行一些通用任務(wù)。過(guò)濾器可以在請(qǐng)求到達(dá)servlet或JSP之前攔截請(qǐng)求,也可以在響應(yīng)發(fā)送回客戶端之前對(duì)其進(jìn)行修改。
public class LoginFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; HttpSession session = httpRequest.getSession(false); boolean isLoggedIn = (session != null && session.getAttribute("user") != null); String loginURI = httpRequest.getContextPath() + "/login"; boolean isLoginRequest = httpRequest.getRequestURI().equals(loginURI); boolean isLoginPage = httpRequest.getRequestURI().endsWith("login.jsp"); if (isLoggedIn && (isLoginRequest || isLoginPage)) { httpRequest.getRequestDispatcher("/home").forward(request, response); } else if (isLoggedIn || isLoginRequest) { chain.doFilter(request, response); } else { httpResponse.sendRedirect(loginURI); } } }
上述代碼中的過(guò)濾器LoginFilter檢查當(dāng)前用戶是否已經(jīng)登錄,如果已登錄則將請(qǐng)求重定向到主頁(yè),否則將請(qǐng)求重定向到登錄頁(yè)面。
在另一方面,攔截器是基于Java反射機(jī)制的一種特殊組件,它可以攔截請(qǐng)求和響應(yīng)并執(zhí)行特定的操作。與過(guò)濾器不同,攔截器在控制器(Handler)處理之前,或之后執(zhí)行,因此它可以訪問(wèn)更多的信息,例如請(qǐng)求上下文和控制器處理的詳細(xì)信息。
public class LoggingInterceptor implements HandlerInterceptor { private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.info("Before handling request"); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { logger.info("After handling request"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { logger.info("After rendering view"); } }
上述代碼中的攔截器LoggingInterceptor在控制器處理請(qǐng)求之前、之后以及視圖渲染完成后記錄日志。
決定是使用過(guò)濾器還是攔截器取決于具體的業(yè)務(wù)需求。過(guò)濾器通常用于對(duì)HTTP請(qǐng)求和響應(yīng)進(jìn)行更基本的操作,例如檢查用戶是否已經(jīng)被授權(quán)或過(guò)濾某些請(qǐng)求參數(shù)。攔截器通常用于對(duì)業(yè)務(wù)流程進(jìn)行更深入的操作 ,例如記錄日志或?qū)崿F(xiàn)安全性驗(yàn)證。