Trang chủHướng dẫnJava Servlet Filter: Hướng dẫn chi tiết kèm ví dụ thực tế
Java

Java Servlet Filter: Hướng dẫn chi tiết kèm ví dụ thực tế

CyStack blog 9 phút để đọc
CyStack blog11/06/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 9 minutes

Trong bài viết này, chúng ta sẽ cùng khám phá Java Servlet Filter – một thành phần quan trọng giúp can thiệp vào luồng xử lý của request và response trong ứng dụng web.

Bài viết sẽ trình bày các tình huống sử dụng phổ biến, hướng dẫn cách xây dựng một filter từ đầu, và minh họa bằng ví dụ thực tế để bạn có thể dễ dàng áp dụng vào dự án của mình.

Java Servlet Filter

Servlet Filter là gì?

Java Servlet Filter là một thành phần thuộc Java EE dùng để can thiệp vào luồng xử lý của request và response trước khi chúng được xử lý bởi servlet hoặc sau khi servlet đã xử lý xong.

Nói cách khác, filter hoạt động như một lớp trung gian cho phép bạn:

  • Chặn, thay đổi, hoặc ghi log các request/response.

  • Thực hiện xác thực, phân quyền, nén dữ liệu, ghi log, xử lý mã hóa ký tự, v.v.

  • Áp dụng logic dùng chung cho nhiều servlet mà không phải viết lại nhiều lần.

Tại sao chúng ta cần Servlet Filter?

Trong bài viết trước, tôi đã chia sẻ cách quản lý phiên trong ứng dụng web. Nếu muốn đảm bảo một tài nguyên chỉ có thể truy cập khi phiên người dùng hợp lệ, chúng ta có thể làm điều này bằng cách sử dụng các thuộc tính phiên servlet.

Cách tiếp cận này khá đơn giản nhưng khó duy trì nếu có quá nhiều servlet và JSP, vì sẽ có rất nhiều mã trùng lặp. Hơn nữa, nếu sau này chúng ta cần thay đổi tên thuộc tính, sẽ phải sửa đổi ở tất cả những nơi có xác thực phiên. Đó là lý do tại sao chúng ta cần đến servlet filter.

Về cơ bản, Servlet Filter là các thành phần Java có thể tích hợp dễ dàng (pluggable). Chức năng của chúng là chặn và xử lý các yêu cầu đến trước khi chúng được chuyển tới servlet, cũng như xử lý các phản hồi sau khi servlet đã xong việc và trước khi container gửi lại cho client. Một số tác vụ phổ biến của servlet filter là:

  • Ghi nhật ký các tham số yêu cầu vào tệp nhật ký.
  • Xác thực và ủy quyền yêu cầu đối với các tài nguyên.
  • Định dạng lại nội dung hoặc tiêu đề của yêu cầu trước khi gửi đến servlet.
  • Nén dữ liệu phản hồi được gửi đến client.
  • Thay đổi phản hồi bằng cách thêm một số cookie, thông tin tiêu đề, v.v.

Như tôi đã đề cập trước đó, servlet filter có thể được tích hợp dễ dàng và bạn có thể cấu hình chúng trong tệp web.xml. Do servlet và filter hoàn toàn độc lập với nhau, việc thêm hay bớt một filter chỉ đơn giản là chỉnh sửa web.xml. Bạn có thể áp dụng nhiều filter cho cùng một tài nguyên, và thậm chí còn có thể sắp xếp chúng thành một chuỗi filter ngay trong web.xml. Để tạo một Servlet Filter, chúng ta sẽ triển khai giao diện javax.servlet.Filter.

Giao diện Servlet Filter

Giao diện Servlet Filter trong Java tương tự như giao diện Servlet. Chúng ta cần triển khai giao diện này để tạo ra bộ lọc servlet của riêng mình. Giao diện này chứa các phương thức vòng đời của một Filter, và toàn bộ quá trình được quản lý bởi servlet container. Các phương thức vòng đời của giao diện Servlet Filter bao gồm:

  1. void init(FilterConfig paramFilterConfig) – Được gọi khi container khởi tạo Filter. Phương thức này chỉ được gọi một lần duy nhất và dùng để khởi tạo tài nguyên. FilterConfig cung cấp các tham số khởi tạo và đối tượng servlet context cho Filter. Có thể ném ServletException cho phương thức này.
  2. doFilter(ServletRequest paramServletRequest, ServletResponse paramServletResponse, FilterChain paramFilterChain) – Được container gọi mỗi khi nó cần áp dụng filter cho một tài nguyên. Container cung cấp các đối tượng yêu cầu và phản hồi cho filter. FilterChain dùng để gọi filter tiếp theo trong chuỗi. Đây là ví dụ của Chain of Responsibility Pattern (Mẫu chuỗi trách nhiệm).
  3. void destroy() – Được container gọi khi loại bỏ (offload) instance của Filter. Phương thức này chỉ được gọi một lần và dùng để đóng/giải phóng các tài nguyên mà filter đã mở.

Annotation Servlet WebFilter

Kể từ Servlet 3.0, chúng ta có thể sử dụng annotation @WebFilter để khai báo servlet filter một cách tiện lợi. Annotation này cho phép bạn thiết lập các tham số khởi tạo, tên, mô tả, và chỉ định rõ filter sẽ hoạt động với servlet nào, theo mẫu URL nào, hoặc loại dispatcher nào.

Mặc dù vậy, nếu cấu hình filter của bạn thường xuyên thay đổi, web.xml vẫn là lựa chọn tốt hơn vì nó không yêu cầu bạn phải biên dịch lại lớp filter.

Cấu hình Servlet Filter trong web.xml

Chúng ta có thể khai báo một servlet filter trong web.xml như mẫu dưới đây:

<filter>
    <filter-name>RequestLoggingFilter</filter-name> <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class>
    <init-param> <param-name>test</param-name>
        <param-value>testValue</param-value>
    </init-param>
</filter>

Chúng ta có thể ánh xạ (map) một Filter tới các lớp servlet hoặc các mẫu URL như dưới đây.

<filter-mapping>
    <filter-name>RequestLoggingFilter</filter-name> <url-pattern>/*</url-pattern> <servlet-name>LoginServlet</servlet-name>

    <dispatcher>REQUEST</dispatcher>
</filter-mapping>

Lưu ý: Khi bạn tạo một chuỗi filter cho servlet, điều quan trọng cần nhớ là container sẽ ưu tiên xử lý các url-pattern trước, sau đó mới đến các servlet-name. Vì vậy, nếu bạn muốn đảm bảo các filter được thực thi theo một thứ tự cụ thể, hãy đặc biệt lưu ý cách bạn định nghĩa filter-mapping. Thông thường, Servlet Filter được dùng cho các yêu cầu trực tiếp từ client.

Tuy nhiên, đôi khi chúng ta cũng muốn áp dụng filter khi yêu cầu được chuyển tiếp thông qua RequestDispatcher. Trong những trường hợp như vậy, bạn có thể sử dụng phần tử <dispatcher> với các giá trị như REQUEST, FORWARD, INCLUDE, ERROR, và ASYNC. Nếu bạn không định nghĩa bất kỳ dispatcher nào, filter sẽ chỉ được áp dụng cho các yêu cầu đến trực tiếp từ client.

Ví dụ về Servlet Filter để ghi nhật ký và xác thực phiên

Trong ví dụ về servlet filter, chúng ta sẽ tạo các filter để ghi nhật ký cookie và tham số yêu cầu.

<!DOCTYPE html>
<html>
<head>
<meta charset="US-ASCII">
<title>Login Page</title>
</head>
<body>
<form action="LoginServlet" method="post">
Username: <input type="text" name="user">
<br>
Password: <input type="password" name="pwd">
<br>
<input type="submit" value="Login">
</form>
</body>
</html>

LoginServlet được sử dụng để xác thực yêu cầu từ client cho việc đăng nhập.

package com.journaldev.servlet.session;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class LoginServlet
 */
@WebServlet("/LoginServlet")
public class LoginServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private final String userID = "admin"; [cite: 44]
    private final String password = "password"; [cite: 44]

    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // lấy các tham số yêu cầu cho userID và password
        String user = request.getParameter("user"); [cite: 45]
        String pwd = request.getParameter("pwd"); [cite: 46]

        if(userID.equals(user) && password.equals(pwd)){
            HttpSession session = request.getSession();
            session.setAttribute("user", "Pankaj"); [cite: 47]
            // cài đặt phiên hết hạn trong 30 phút
            session.setMaxInactiveInterval(30*60);
            response.sendRedirect("LoginSuccess.jsp"); [cite: 47]
        }else{
            Cookie userName = new Cookie("user", user);
            userName.setMaxAge(30*60);
            response.addCookie(userName);
            RequestDispatcher rd = getServletContext().getRequestDispatcher("/login.html"); [cite: 48]
            PrintWriter out= response.getWriter();
            out.println("<font color=red>Either user name or password is wrong.</font>"); [cite: 48]
            rd.include(request, response);
        }
    }
}

Khi client được xác thực, nó sẽ được chuyển tiếp đến LoginSuccess.jsp.

<%@ page language="java" contentType="text/html; charset=US-ASCII"
    pageEncoding="US-ASCII"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<https://www.w3.org/TR/html4/loose.dtd>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII"> [cite: 50]
<title>Login Success Page</title>
</head>
<body>
<%
// chỉ cho phép truy cập nếu phiên tồn tại
String user = (String) session.getAttribute("user");
String userName = null;
String sessionID = null;
Cookie[] cookies = request.getCookies();
if(cookies !=null){
    for(Cookie cookie : cookies){
        if(cookie.getName().equals("user")) userName = cookie.getValue();
        if(cookie.getName().equals("JSESSIONID")) sessionID = cookie.getValue();
    }
}
%>
<h3>Xin chào <%=userName %>, Đăng nhập thành công. ID phiên của bạn =<%=sessionID %></h3>
<br>
Người dùng =<%=user %>
<br>
<a href="CheckoutPage.jsp">Trang Thanh toán</a>
<form action="LogoutServlet" method="post">
<input type="submit" value="Đăng xuất" >
</form>
</body>
</html>

Lưu ý rằng không có logic xác thực phiên nào trong JSP ở trên. Nó chứa một liên kết đến CheckoutPage.jsp.

<%@ page language="java" contentType="text/html; charset=US-ASCII" [cite: 51]
pageEncoding="US-ASCII"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<https://www.w3.org/TR/html4/loose.dtd>">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Login Success Page</title>
</head>
<body>
<%
String userName = null;
String sessionID = null; [cite: 52]
Cookie[] cookies = request.getCookies();
if(cookies !=null){
    for(Cookie cookie : cookies) {

        if(cookie.getName().equals("user")) userName = cookie.getValue(); [cite: 54]
    }
}
%>
<h3>Xin chào <%=userName %>, hãy thanh toán.</h3>
<br>
<form action="LogoutServlet" method="post">
<input type="submit" value="Đăng xuất" >
</form>
</body>
</html>

LogoutServlet được gọi khi client nhấp vào nút Đăng xuất trên bất kỳ trang JSP nào.

package com.journaldev.servlet.session; [cite: 55]

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * Servlet implementation class LogoutServlet
 */
@WebServlet("/LogoutServlet")
public class LogoutServlet extends HttpServlet {
    private static final long serialVersionUID = 1L; [cite: 57]

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            for(Cookie cookie : cookies) {
                if(cookie.getName().equals("JSESSIONID")) {
                    System.out.println("JSESSIONID="+cookie.getValue()); [cite: 58]
                    break;
                }
            }
        }
        // vô hiệu hóa phiên nếu tồn tại
        HttpSession session = request.getSession(false);
        System.out.println("User="+session.getAttribute("user"));
        if(session != null) {

            session.invalidate(); [cite: 59]
        }
        response.sendRedirect("login.html");
    }
}

Bây giờ chúng ta sẽ tạo các lớp servlet filter để ghi nhật ký và xác thực.

package com.journaldev.servlet.filters; [cite: 60]

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter; [cite: 61]
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

/**
 * Servlet Filter implementation class RequestLoggingFilter
 */
@WebFilter("/RequestLoggingFilter")
public class RequestLoggingFilter implements Filter {

    private ServletContext context;

    public void init(FilterConfig fConfig) throws ServletException { [cite: 62]
        this.context = fConfig.getServletContext();
        this.context.log("RequestLoggingFilter initialized"); [cite: 63]
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        Enumeration<String> params = req.getParameterNames();

        while(params.hasMoreElements()){
            String name = params.nextElement();
            String value = request.getParameter(name);
            this.context.log(req.getRemoteAddr() + ":: Request Params::{" + name + "=" + value + "}");
        }

        Cookie[] cookies = req.getCookies();

        if(cookies != null){
            for(Cookie cookie : cookies) {
                this.context.log(req.getRemoteAddr() + ":: Cookie::{" + cookie.getName() + "," + cookie.getValue() + "}");
            }
        }
        // chuyển tiếp yêu cầu dọc theo chuỗi filter
        chain.doFilter(request, response);
    }

    public void destroy() {
        // chúng ta có thể đóng tài nguyên ở đây
    }
}

package com.journaldev.servlet.filters;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebFilter("/AuthenticationFilter")
public class AuthenticationFilter implements Filter {

    private ServletContext context;

    public void init(FilterConfig fConfig) throws ServletException {
        this.context = fConfig.getServletContext();
        this.context.log("AuthenticationFilter initialized"); [cite: 65]
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;

        String uri = req.getRequestURI();
        this.context.log("Requested Resource::" + uri);

        HttpSession session = req.getSession(false); [cite: 66]
        if(session == null && ! (uri.endsWith("html") || uri.endsWith("LoginServlet"))){ [cite: 67]
            this.context.log("Unauthorized access request");
            res.sendRedirect("login.html");
        }else{
            // chuyển tiếp yêu cầu dọc theo chuỗi filter
            chain.doFilter(request, response);
        }
    }

    public void destroy() {
        // đóng bất kỳ tài nguyên nào ở đây
    }
}

Lưu ý rằng chúng ta không xác thực bất kỳ trang HTML hoặc LoginServlet nào. Bây giờ chúng ta sẽ cấu hình web.xml như sau:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="<https://www.w3.org/2001/XMLSchema-instance>" xmlns="<https://java.sun.com/xml/ns/javaee>" xsi:schemaLocation="<https://java.sun.com/xml/ns/javaee> <https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd>" display-name="ServletFilterExample" version="3.0">
    <display-name>ServletFilterExample</display-name>
    <welcome-file-list>
        <welcome-file>login.html</welcome-file>
    </welcome-file-list>

    <filter>
        <filter-name>RequestLoggingFilter</filter-name>
        <filter-class>com.journaldev.servlet.filters.RequestLoggingFilter</filter-class>
    </filter>

    <filter>
        <filter-name>AuthenticationFilter</filter-name>
        <filter-class>com.journaldev.servlet.filters.AuthenticationFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>RequestLoggingFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

    <filter-mapping>
        <filter-name>AuthenticationFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Bây giờ khi chạy ứng dụng, chúng ta sẽ nhận được các phản hồi như dưới đây.

Ngày 13 tháng 8, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Ngày 13 tháng 8, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/
Ngày 13 tháng 8, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Unauthorized access request
Ngày 13 tháng 8, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Ngày 13 tháng 8, 2013 1:06:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Request Params::{pwd=password}
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Request Params::{user=admin}
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,B7275762B8D23121152B1270D6EB240A}
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginServlet
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Ngày 13 tháng 8, 2013 1:06:43 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
Ngày 13 tháng 8, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} [cite: 70]
Ngày 13 tháng 8, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin} [cite: 70]
Ngày 13 tháng 8, 2013 1:06:52 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/CheckoutPage.jsp
Ngày 13 tháng 8, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Ngày 13 tháng 8, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Ngày 13 tháng 8, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LogoutServlet
JSESSIONID=8BDF777933194EDCAC1D8F1B73633C56
User=Pankaj
Ngày 13 tháng 8, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Ngày 13 tháng 8, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Ngày 13 tháng 8, 2013 1:07:00 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html
Ngày 13 tháng 8, 2013 1:07:06 AM org.apache.catalina.core.ApplicationContext log [cite: 71]

INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56} [cite: 72]
Ngày 13 tháng 8, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Ngày 13 tháng 8, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/LoginSuccess.jsp
Ngày 13 tháng 8, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Unauthorized access request
Ngày 13 tháng 8, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{JSESSIONID,8BDF777933194EDCAC1D8F1B73633C56}
Ngày 13 tháng 8, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: 0:0:0:0:0:0:0:1%0::Cookie::{user,admin}
Ngày 13 tháng 8, 2013 1:07:07 AM org.apache.catalina.core.ApplicationContext log
INFO: Requested Resource::/ServletFilterExample/login.html

Như vậy là chúng ta đã tìm hiểu về Servlet Filter trong Java. Tóm lại, đây là một tính năng quan trọng trong ứng dụng web Java EE. Chúng cho phép chúng ta chặn và xử lý các yêu cầu cũng như phản hồi một cách linh hoạt, giúp thực hiện các tác vụ chung như ghi nhật ký hay xác thực một cách hiệu quả và dễ bảo trì.

Ngoài ra, các framework như Struts 2 cũng đã ứng dụng Servlet Filter để chặn các yêu cầu từ client và chuyển hướng chúng đến các lớp hành động phù hợp, mà trong Struts 2 chúng được gọi là Interceptor.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất