Servlet-Filter

Trong Java Servlet, Filter (Bộ lọc) là một cơ chế cho phép bạn xử lý yêu cầu trước khi chúng được gửi đến Servlet và xử lý phản hồi trước khi chúng được gửi đến khách hàng. Filter là một thành phần rất quan trọng trong ứng dụng web để thực hiện các nhiệm vụ như kiểm tra xác thực, kiểm tra quyền truy cập, nén dữ liệu và ghi nhật ký.

Một Filter được thực thi trước khi yêu cầu được gửi đến Servlet hoặc sau khi phản hồi được trả về từ Servlet. Filter được cấu hình để chỉ xử lý các yêu cầu hoặc phản hồi từ một URL hoặc một loại tài nguyên nhất định.

Để tạo một Filter trong Java Servlet, bạn cần triển khai giao diện javax.servlet.Filter và cung cấp thực hiện phương thức doFilter() để xử lý yêu cầu và phản hồi. Ví dụ, để tạo một bộ lọc đơn giản để ghi nhật ký tất cả các yêu cầu, bạn có thể sử dụng đoạn mã sau:

import java.io.*;
public class LoggingFilter implements Filter {
   public void init(FilterConfig config) throws ServletException {
      // Khởi tạo Filter
   }
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
      // Xử lý yêu cầu trước khi gửi đến Servlet
      System.out.println("Request received: " + request.getRemoteAddr());
      // Chuyển tiếp yêu cầu đến Servlet tiếp theo trong chuỗi
      chain.doFilter(request, response);
      // Xử lý phản hồi trước khi gửi đến khách hàng
      System.out.println("Response sent: " + response.getContentType());
   }
   public void destroy() {
      // Hủy Filter
   }
}

Trong đoạn mã này, lớp LoggingFilter triển khai giao diện Filter và triển khai phương thức init(), doFilter()destroy(). Trong phương thức doFilter(), đầu vào ServletRequestServletResponse được sử dụng để xử lý yêu cầu trước khi gửi đến Servlet và xử lý phản hồi trước khi gửi đến khách hàng. Phương thức chain.doFilter() được sử dụng để chuyển tiếp yêu cầu đến Servlet tiếp theo trong chuỗi.

Để sử dụng bộ lọc này, bạn cần cấu hình nó trong tệp web.xml của ứng dụng web. Ví dụ:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>LogFilter</filter-class>
   <init-param>
	  <param-name>test-param</param-name>
	  <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>
<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Filter trên sẽ áp dụng cho tất cả Servlet bởi vì chúng ta xác định /* trong cấu hình. Bạn có thể xác định một Servlet path cụ thể nếu bạn chỉ muốn áp dụng Filter trên một số Servlet nào đó.

Sử dụng nhiều Filter trong Servlet

Ứng dụng web của bạn có thể định nghĩa một vài Filter cho một mục đích nào đó. Giả sử bạn định nghĩa hai Filter là AuthenFilter và LogFilter. Phần còn lại của tiến trình sẽ giống như ví dụ trên, ngoại trừ việc bạn cần tạo một ánh xạ khác như dưới đây:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>LogFilter</filter-class>
   <init-param>
	  <param-name>test-param</param-name>
	  <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter>
   <filter-name>AuthenFilter</filter-name>
   <filter-class>AuthenFilter</filter-class>
   <init-param>
	  <param-name>test-param</param-name>
	  <param-value>Initialization Paramter</param-value>
   </init-param>
</filter>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

Thứ bậc của các Filter

Bậc của Filter trong web.xml quyết định thứ tự mà Web container áp dụng Filter tới các Servlet. Để đảo ngược thứ tự của Filter, bạn chỉ cần đảo ngược các phần tử ánh xạ Filter trong web.xml.

Trong ví dụ trên, LogFilter sẽ được áp dụng đầu tiên và sau đó áp dụng AuthenFilter tới bất kỳ Servlet nào. Nhưng trong ví dụ sau, thứ tự này sẽ bị đảo ngược.

<filter-mapping>
   <filter-name>AuthenFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

<filter-mapping>
   <filter-name>LogFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>