English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Servlet 필터 작성

Servlet 필터는 요청과 응답을 동적으로 차단하여 요청이나 응답에 포함된 정보를 변환하거나 사용할 수 있습니다。

한 개나 여러 개의 Servlet 필터를 Servlet이나 Servlet 그룹에 추가할 수 있습니다. Servlet 필터는 JavaServer Pages (JSP) 파일과 HTML 페이지에도 추가할 수 있습니다. Servlet를 호출하기 전에 모든 추가된 Servlet 필터를 호출합니다。

Servlet 필터는 Servlet 프로그래밍에 사용할 수 있는 Java 클래스로 다음 목적을 달성할 수 있습니다:

  • 클라이언트의 요청이 백엔드 자원에 접근하기 전에 이를 차단합니다。

  • 서버의 응답이 클라이언트로 전송되기 전에 이를 처리합니다。

규격에 따라 제안된 여러 유형의 필터를 기준으로 합니다:

  • Authentication Filters).

  • Data compression Filters).

  • Encryption Filters).

  • Resource Access Event Triggering Filters.

  • Image Conversion Filters).

  • Logging and Auditing Filters).

  • MIME-TYPE MIME Chain Filters).-TYPE Chain Filters).

  • Tokenizing Filters).

  • XSL/T 필터(XSL)/T Filters), XML 내용을 변환합니다.

필터는 web.xml 배포 설명자의 XML 태그를 통해 선언되고, 이후应用程序의 배포 설명자에 있는 Servlet 이름이나 URL 패턴에 매핑됩니다.

웹 컨테이너가 웹 애플리케이션을 시작할 때, 배포 설명자(deployment descriptor)에 명시된 각 필터에 대해 예제를 생성합니다.

필터의 실행 순서는 web.xml 설정 파일에配置된 순서와 일치하며, 일반적으로 모든 Servlet 앞에 필터를 설정합니다.

Servlet 필터 메서드

필터는 javax.servlet.Filter 인터페이스를 구현한 Java 클래스입니다. javax.servlet.Filter 인터페이스는 세 가지 메서드를 정의합니다:

순번메서드 & 설명
1public void doFilter (ServletRequest, ServletResponse, FilterChain)
이 메서드는 실제 필터 작업을 완료합니다. 클라이언트가 요청하는 메서드가 필터 설정된 URL과 일치할 때, Servlet 컨테이너는 필터의 doFilter 메서드를 호출합니다. FilterChain은 이후 필터에 접근합니다.
2public void init(FilterConfig filterConfig)
웹 애플리케이션이 시작될 때, 웹 서버는 Filter의 예제 객체를 생성하고 init 메서드를 호출하여 web.xml 설정을 읽고, 객체의 초기화 기능을 완료하여 이후 사용자 요청에 대한 차단 준비를 하게 합니다(필터 객체는 한 번만 생성되고, init 메서드는 한 번만 실행됩니다). 개발자는 init 메서드의 파라미터를 통해 현재 필터 설정 정보를 대표하는 FilterConfig 객체를 얻을 수 있습니다.
3public void destroy()
Servlet 容器在销毁过滤器示例前调用该方法,在该方法中释放 Servlet 过滤器占用的资源。

FilterConfig 使用

Filter 的 init 方法中提供了一个 FilterConfig 对象。

如 web.xml 文件配置如下:

<filter>
    <filter-name>LogFilter</filter-name>
    <filter-class>com.w3codebox.test.LogFilter</filter-class>
    <init-param>
        <param-name>Site</param-name>
        <param-value>기본 튜토리얼 웹사이트</param-value>
    </init-param>
</filter>

在 init 方法使用 FilterConfig 对象获取参数:

public void init(FilterConfig config) throws ServletException {
    // 获取初始化参数
    String site = config.getInitParameter("Site"); 
    // 输出初始化参数
    System.out.println("网站名称: " + site); 
}

Servlet 过滤器示例

以下是 Servlet 过滤器的示例,将输出网站名称和地址。本示例让您对 Servlet 过滤器有基本的了解,您可以使用相同的概念编写更复杂的过滤器应用程序:

package com.w3codebox.test;
//导入必需的 java 库
import javax.servlet.*;
import java.util.*;
//实现 Filter 类
public class LogFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
        // 获取初始化参数
        String site = config.getInitParameter("Site"); 
        // 输出初始化参数
        System.out.println("网站名称: " + site); 
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
        // 输出站点名称
        System.out.println("站点网址:http://ko.oldtoolbag.com");
        // 把请求传回过滤链
        chain.doFilter(request,response);
    }
    public void destroy( ){
        /* 在 Filter 示例被 Web 容器从服务移除之前调用 */
    }
}

这边使用前文提到的 DisplayHeader.java 为实例:

//导入必需的 java 库
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DisplayHeader)
//HttpServlet 클래스 확장
public class DisplayHeader extends HttpServlet
    // GET 메서드 요청 처리 메서드
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 설정 응답 내용 타입
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String title = "HTTP Header 요청 예제 - 基础教程网示例";
        String docType =
            "<!DOCTYPE html> \n";
            out.println(docType +
            "<html>\n" +
            "<head><meta charset=\"utf-8\"><title>" + title + "</title></head>\n"+
            "<body bgcolor=\"#f0f0f0\">\n" +
            "<h1 align=\"center\">" + title + "</h1>\n" +
            "<table width=\"100%\" border=\"1\" align=\"center\">\n" +
            "<tr bgcolor=\"#949494\">\n" +
            "<th>Header 名称</th><th>Header 값</th>\n"+
            "</tr>\n");
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String paramName = (String)headerNames.nextElement();
            out.print("<tr><td>" + paramName + "</td>\n");
            String paramValue = request.getHeader(paramName);
            out.println("<td> " + paramValue + "</td></tr>\n");
        }
        out.println("</table>\n</body></html>");
    }
    // POST 메서드 요청을 처리하는 메서드
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Web.xml의 Servlet 필터 매핑(Servlet Filter Mapping)

필터를 정의하고 URL이나 Servlet에 매핑을 할 때, Servlet을 정의하고 URL 패턴에 매핑하는 방식과 비슷합니다. 배포 설명서 파일 web.xml filter 태그에 아래 항목을 생성합니다:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app>  
<filter>
  <filter-name>LogFilter</filter-name>
  <filter-class>com.w3codebox.test.LogFilter</filter-class>
  <init-param>
    <param-name>Site</param-name>
    <param-value>기본 튜토리얼 웹사이트</param-value>
  </init-param>
</filter>
<filter-mapping>
  <filter-name>LogFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>  
  <!-- 클래스 이름 -->  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- 소속 패키지 -->  
  <servlet-class>com.w3codebox.test.DisplayHeader</servlet-class>  
</servlet>  
<servlet-mapping>  
  <servlet-name>DisplayHeader</servlet-name>  
  <!-- 방문한 웹사이트 -->  
  <url-pattern>/TomcatTest/DisplayHeader</url-pattern>  
</servlet-mapping>  
</web-app>

위의 필터는 모든 Servlet에 적용됩니다. 왜냐하면 우리는 설정에서 지정했기 때문입니다. /* 만약 일부 Servlet에만 필터를 적용하고 싶다면, 특정 Servlet 경로를 지정할 수 있습니다.

일반적인 방식으로 어떤 Servlet을 호출해 보세요. 웹 서버에서 생성된 로그를 볼 수 있습니다. 또한 Log를 사용할 수도 있습니다.4J 레코드어를 사용하여 위의 로그를 별도의 파일에 기록합니다.

이제 이 예제 주소에 접근해 보겠습니다 http://localhost:8080/TomcatTest/DisplayHeader,然后在控制台查看输出内容,如下所示:

使用多个过滤器

Web应用程序可以根据特定的目的定义多个不同的过滤器。假设您定义了两个过滤器 AuthenFilterLogFilter。이제 다음과 같은 다른 매핑을 생성해야 하며,나머지 처리는 위에서 설명한 것과 유사합니다:

<filter>
   <filter-name>LogFilter</filter-name>
   <filter-class>com.w3codebox.test.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>com.w3codebox.test.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>

필터 적용 순서

web.xml에서의 filter-mapping 요소의 순서는 Web 컨테이너가 Servlet에 필터를 적용하는 순서를 결정합니다. 필터 순서를 반전하려면 web.xml 파일에서 filter를 반전하면 됩니다-mapping 요소만으로도 됩니다。

예를 들어,위의 예제는 먼저 LogFilter를 적용한 후 AuthenFilter를 적용하지만,다음 예제는 이 순서를 뒤집습니다:

<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>

web.xml 설정 각 노드 설명

  • <filter> 필터를 지정합니다。

    • <filter-name> 필터에 이름을 지정하는 데 사용되며,이 요소의 내용은 비어서는 안 됩니다。

    • <filter-class> 요소는 필터의 전체 제한 클래스 이름을 지정합니다。

    • <init-param> 요소는 필터에 초기화 매개변수를 지정하기 위해 사용되며,그 자식 요소 <param-name> 매개변수 이름을 지정합니다,<param-value> 매개변수의 값을 지정합니다。

    • 필터에서는 FilterConfig 인터페이스 객체를 사용하여 초기화 매개변수에 접근할 수 있습니다.

  • <filter-mapping> 요소는 하나의 Filter가 책임지는 중지 자원을 설정합니다. Filter가 중지하는 자원은 두 가지 방식으로 지정할 수 있습니다: Servlet 이름과 자원 접근의 요청 경로

    • <filter-name>이 요소는 filter를 설정하는 등록 이름을 사용합니다. 이 값은 <filter> 요소에서 선언된 필터 이름이어야 합니다

    • <url-pattern>은 필터가 차단하는 요청 경로(필터와 연관된 URL 스타일)을 설정합니다.

  • <servlet-name>은 필터가 차단하는 Servlet 이름을 지정합니다.

  • <dispatcher>는 필터가 차단하는 자원이 Servlet 컨테이너에 의해 호출되는 방식을 지정합니다. REQUEST, INCLUDE, FORWARD, ERROR 중 하나입니다. 기본적으로 REQUEST입니다. 사용자는 Filter가 자원에 대해 여러 가지 호출 방식을 차단하도록 여러 개의 <dispatcher> 서브 요소를 설정할 수 있습니다.

  • <dispatcher> 서브 요소가 설정할 수 있는 값과 의미

    • REQUEST: 사용자가 직접 페이지에 접근했을 때, 웹 컨테이너가 필터를 호출합니다. 목표 자원이 RequestDispatcher의 include() 또는 forward() 메서드를 통해 접근되었을 때, 이 필터는 호출되지 않습니다.

    • INCLUDE: 목표 자원이 RequestDispatcher의 include() 메서드를 통해 접근되었을 때, 이 필터가 호출됩니다. 그렇지 않으면, 이 필터는 호출되지 않습니다.

    • FORWARD: 목표 자원이 RequestDispatcher의 forward() 메서드를 통해 접근되었을 때, 이 필터가 호출됩니다. 그렇지 않으면, 이 필터는 호출되지 않습니다.

    • ERROR: 목표 자원이 선언적 예외 처리 메커니즘을 통해 호출되었을 때, 이 필터가 호출됩니다. 그렇지 않으면, 필터는 호출되지 않습니다.