CodeGym/Khóa học Java/Mô-đun 3/Bộ lọc máy chủ web

Bộ lọc máy chủ web

Có sẵn

Giới thiệu về bộ lọc

Nhưng đó không phải là tất cả. Bạn thực sự không nghĩ rằng servlet đơn giản như vậy, phải không?

Ngoài các servlet mà chúng tôi đã phân tích, còn có cái gọi là “servlet tiện ích” - bộ lọc . Chúng rất giống với servlet, nhưng công việc chính của chúng là giúp servlet xử lý các yêu cầu.

Bộ lọc giống như một thư ký và một servlet giống như một giám đốc. Trước khi tài liệu đến bàn giám đốc, nó sẽ qua tay thư ký. Và sau khi giám đốc ký, nó sẽ lại được chuyển đến thư ký, chẳng hạn như thư từ gửi đi chẳng hạn.

Một thư ký như vậy có thể từ chối một số yêu cầu đối với giám đốc (ví dụ: thư rác). Hoặc đưa ra câu trả lời tiêu chuẩn cho những câu hỏi mà anh ấy biết (“giám đốc không có mặt”). Và như thế. Hơn nữa, có thể có một số thư ký như vậy: một thư ký có thể lọc thư rác cho tất cả các giám đốc cùng một lúc, thư ký kia có thể chuyển yêu cầu giữa các giám đốc khác nhau, v.v.

Bộ lọc hoạt động theo cùng một cách.

servlet tiện ích”

Lớp Lọc, FilterChain, FilterConfig

Các bộ lọc rất giống với các servlet, nhưng có một số khác biệt nhỏ. Để viết bộ lọc của riêng bạn, bạn cần kế thừa từ javax.servlet.Filter.

Bộ lọc cũng có các phương thức init()destroy(). Thay vì một phương thức, service()một bộ lọc có phần mở rộng doFilter(). Và thậm chí có lớp FilterConfig riêng. Bộ lọc cũng được thêm vào servlet trong tệp web.xml hoặc thông qua chú thích @WebFilter.

Danh sách các phương pháp:

phương pháp Sự miêu tả
1 init(FilterConfig config) khởi tạo bộ lọc
2 destroy() dỡ bộ lọc
3 doFilter(ServletRequest , ServletResponse, FilterChain) xử lý yêu cầu (lọc)

Sự khác biệt giữa servlet và bộ lọc là gì?

Có thể có một số bộ lọc và chúng sẽ xử lý tuần tự yêu cầu (và phản hồi). Chúng được kết hợp thành cái gọi là chuỗi - và thậm chí còn có một lớp đặc biệt dành cho chúng FilterChain.

Sau khi xử lý yêu cầu trong phương thức, doFilter()bạn cần gọi phương thức doFilter()của bộ lọc tiếp theo trong chuỗi. Ví dụ:

public class MyFilter implements Filter {

  public void init(FilterConfig arg0) throws ServletException {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {

      PrintWriter out = resp.getWriter();
      out.print("Adding something before the body of the response");

      chain.doFilter(req, resp); // call the next filter in the chain

      out.print("Adding something after the body of the response");
    }

  public void destroy() {
  }
}

Trên thực tế, bạn không thể thêm nội dung phản hồi như vậy . Về mặt hình thức, các bộ lọc và servlet độc lập với nhau và có thể thay đổi độc lập. Chúng có thể được viết bởi các nhà phát triển khác nhau vào những thời điểm khác nhau. Chức năng lọc chỉ là một chức năng dịch vụ, ví dụ:

  • Ghi nhật ký tất cả các yêu cầu đến (và phản hồi)
  • Nén dữ liệu
  • Mã hóa (và giải mã) dữ liệu
  • Yêu cầu xác thực dữ liệu
  • Thêm/xóa tiêu đề mong muốn
  • Chuyển hướng yêu cầu
  • Kiểm soát truy cập (kiểm tra xem người dùng đã đăng nhập chưa)

lớp RequestDispatcher

doFilter() Đôi khi có thể cần phải gọi một servlet khác trong khi bộ lọc đang chạy trong một phương thức . Để làm điều này, vùng chứa có một đối tượng đặc biệt RequestDispatcher.

Bạn có thể lấy nó theo hai cách:

  • Tại đối tượngHttpServletRequest
  • Tại đối tượngServletContext

Đối tượng này có thể được sử dụng để chuyển hướng một yêu cầu hiện có sang một servlet khác . Ví dụ: hóa ra người dùng không được ủy quyền và chúng tôi muốn hiển thị cho anh ta một trang được ủy quyền. Chà, hoặc đã xảy ra lỗi trên máy chủ và chúng tôi muốn hiển thị trang lỗi cho người dùng :)

public class HelloServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)  throws Exception {
           String path = "/error.html";
           ServletContext servletContext = this.getServletContext();
           RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
           requestDispatcher.forward(request, response);
    }
}

Bạn cũng có thể gọi RequestDispatchertừ một bộ lọc.

public class MyFilter implements Filter {

  public void init(FilterConfig arg0) throws ServletException {
  }

  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws Exception {
           String path = "/error.html";
           ServletContext servletContext = req.getServletContext();
           RequestDispatcher requestDispatcher = servletContext.getRequestDispatcher(path);
           requestDispatcher.forward(req, resp);
    }

  public void destroy() {
  }
}

Lưu ý rằng yêu cầu sẽ được xử lý trong phương thức forward()và không cần gọi doFilter()sau khi sử dụng RequestDispatcher.

So sánh chuyển hướng và chuyển tiếp

Và một điểm quan trọng nữa. Nếu bạn muốn chuyển hướng người dùng đến một URI khác trong servlet của mình, thì bạn có thể thực hiện việc này theo hai cách:

  • redirect
  • forward

Chúng tôi đã phân tích chúng, nhưng để thuận tiện, tôi sẽ nói lại.

Khi bạn chuyển hướng qua một cuộc gọi response.sendRedirect("link"), máy chủ sẽ gửi lại cho trình duyệt (máy khách) một phản hồi 302và liên kết bạn đã chỉ định. Và trình duyệt, sau khi phân tích phản hồi của máy chủ, sẽ tải xuống liên kết bạn đã chuyển. Đó là, liên kết trong trình duyệt thay đổi thành liên kết mới.

Nếu bạn chuyển tiếp qua một cuộc gọi requestDispatcher.forward()thì một yêu cầu mới sẽ được thực hiện bên trong vùng chứa và servlet của bạn sẽ gửi phản hồi của nó tới trình duyệt (máy khách) dưới dạng phản hồi của servlet của bạn. Trong trường hợp này, trình duyệt nhận được phản hồi từ servlet mới, nhưng liên kết trong trình duyệt không thay đổi.

Bình luận
  • Phổ biến
  • Mới
Bạn phải đăng nhập để đăng nhận xet
Trang này chưa có bất kỳ bình luận nào