> Java > java지도 시간 > 본문

Java의 필터에 대한 자세한 설명

高洛峰
풀어 주다: 2017-02-08 11:41:05
원래의
1600명이 탐색했습니다.

필터 소개

필터는 서블릿 기술 중 가장 실용적인 기술로, WEB 개발자는 Jsp, Servlet, Intercept 등 웹 서버에서 관리하는 모든 웹 리소스를 관리하기 위해 사용합니다. 정적 이미지 파일이나 정적 HTML 파일을 사용하여 일부 특수 기능을 수행할 수 있습니다. 예를 들어, URL 수준의 권한 접근 제어, 민감한 어휘 필터링, 응답 정보 압축 등 일부 고급 기능을 구현할 수 있습니다.

주로 사용자 요청을 전처리하는 데 사용되며 HttpServletResponse를 후처리할 수도 있습니다. 필터 사용의 전체 프로세스: 필터는 사용자 요청을 전처리한 다음 처리를 위해 요청을 서블릿에 전달하고 응답을 생성하며 마지막으로 필터는 서버 응답을 후처리합니다.

필터 기능

클라이언트의 HttpServletRequest가 서블릿에 도달하기 전에 가로챕니다. 필요에 따라 HttpServletRequest를 확인하고 HttpServletRequest 헤더 및 데이터를 수정합니다.

클라이언트에 도달하기 전에 HttpServletResponse를 가로채세요. 필요에 따라 HttpServletResponse를 확인하고 HttpServletResponse 헤더 및 데이터를 수정합니다.

Filter를 사용하여 차단 기능을 구현하는 방법

Filter 인터페이스에는 doFilter 메소드가 있습니다. 개발자가 Filter를 작성하고 차단할 웹 리소스를 구성하면 WEB 서버가 작동합니다. 매번 웹 리소스를 호출합니다. 리소스의 서비스 메서드를 호출하기 전에 필터의 doFilter 메서드가 먼저 호출됩니다. 따라서 이 메서드에 코드를 작성하면 다음과 같은 목적을 달성할 수 있습니다. 코드는 대상 리소스를 호출하기 전에 실행됩니다.

대상 리소스를 호출할지 여부(즉, 사용자가 웹 리소스에 액세스하도록 허용할지 여부).

웹 서버는 doFilter 메소드를 호출할 때 filterChain 객체를 전달합니다. filterChain 객체는 필터 인터페이스에서 가장 중요한 객체이기도 하며 개발자는 이를 호출할지 여부를 결정할 수 있습니다. 이 메서드가 호출되면 웹 서버는 웹 리소스의 서비스 메서드를 호출합니다. 즉, 웹 리소스에 액세스하고 그렇지 않으면 웹 리소스에 액세스하지 않습니다.

필터 개발을 위한 2단계

필터 인터페이스를 구현하고 해당 doFilter 메소드를 구현하는 Java 클래스를 작성합니다.

web.xml 파일의 및 요소를 사용하여 작성된 필터 클래스를 등록하고 차단할 수 있는 리소스를 설정합니다.

web.xml 구성의 각 노드 소개:

필터를 지정합니다.

은 필터의 이름을 지정하는 데 사용됩니다. 이 요소의 콘텐츠는 비워둘 수 없습니다.

요소는 필터의 정규화된 클래스 이름을 지정하는 데 사용됩니다.

요소는 필터의 초기화 매개변수를 지정하는 데 사용됩니다. 매개변수의 값.

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

요소는 필터가 가로채기를 담당하는 리소스를 설정하는 데 사용됩니다. 필터가 가로채는 리소스는 두 가지 방법으로 지정할 수 있습니다. 리소스 액세스를 위한 서블릿 이름과 요청 경로

하위 요소는 필터의 등록된 이름을 설정하는 데 사용됩니다. 이 값은 요소에 선언된 필터의 이름이어야 합니다.

필터가 가로채는 요청 경로(필터와 관련된 URL 패턴)를 설정합니다. 🎜 >필터가 가로채는 서블릿의 이름을 지정합니다.

필터가 가로채는 리소스가 서블릿 컨테이너에 의해 호출되는 방식을 지정합니다. REQUEST, INCLUDE, FORWARD 및 ERROR 중 하나일 수 있습니다. 사용자는 여러 하위 요소를 설정하여 리소스의 여러 호출 방법을 가로채도록 필터를 지정할 수 있습니다.

하위 요소에 설정할 수 있는 값과 의미

요청: 사용자가 해당 페이지에 직접 접속하면 웹 컨테이너가 필터를 호출합니다. RequestDispatcher의 include() 또는 전달() 메서드를 통해 대상 리소스에 액세스하는 경우 이 필터는 호출되지 않습니다.

INCLUDE: RequestDispatcher의 include() 메서드를 통해 대상 리소스에 액세스하면 이 필터가 호출됩니다. 그렇지 않으면 필터가 호출되지 않습니다.

FORWARD: RequestDispatcher의 전달() 메서드를 통해 대상 리소스에 액세스하면 이 필터가 호출됩니다. 그렇지 않으면 이 필터가 호출되지 않습니다.

오류: 대상 리소스가 선언적 예외 처리 메커니즘을 통해 호출되면 이 필터가 호출됩니다. 그렇지 않으면 필터가 호출되지 않습니다.

필터 체인

웹 애플리케이션에서는 여러 필터를 개발하고 작성할 수 있습니다. 이러한 필터의 조합을 필터 체인이라고 합니다.

웹 서버는 web.xml 파일에 있는 Filter의 등록 순서에 따라 어떤 Filter를 먼저 호출할지 결정합니다. 첫 번째 Filter의 doFilter 메소드가 호출되면 웹 서버는 다음을 나타내는 FilterChain 객체를 생성합니다. 필터 체인을 전달하고 메소드를 제공하십시오. doFilter 메서드에서 개발자가 FilterChain 개체의 doFilter 메서드를 호출하면 웹 서버는 FilterChain 개체에 다른 필터가 있는지 확인하고, 없으면 두 번째 필터를 호출합니다. 호출됩니다.

필터 수명주기

public void init(FilterConfig filterConfig) throws ServletException;//初始化
로그인 후 복사

우리가 작성한 서블릿 프로그램과 마찬가지로 Filter의 생성과 소멸은 WEB 서버의 몫입니다. 웹 애플리케이션이 시작되면 웹 서버는 Filter의 인스턴스 객체를 생성하고 init 메소드를 호출하고 web.xml 구성을 읽고 객체의 초기화 기능을 완료하여 후속 사용자 요청(필터 객체)을 차단할 준비를 합니다. 한 번만 생성되고 init 메서드는 한 번만 실행됩니다. 개발자는 init 메소드의 매개변수를 통해 현재 필터 구성 정보를 나타내는 FilterConfig 객체를 얻을 수 있습니다.

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//拦截请求
로그인 후 복사

이 방법으로 실제 필터링 작업이 완료됩니다. 클라이언트가 필터와 연관된 URL에 대한 액세스를 요청하면 서블릿 필터는 먼저 doFilter 메소드를 실행합니다. FilterChain 매개변수는 후속 필터에 액세스하는 데 사용됩니다.

public void destroy();//销毁
로그인 후 복사

필터 개체는 생성 후 메모리에 상주하며 웹 애플리케이션이 제거되거나 서버가 중지되면 제거됩니다. 웹 컨테이너가 필터 개체를 언로드하기 전에 호출됩니다. 이 메서드는 필터의 수명 주기 동안 한 번만 실행됩니다. 이 방법을 사용하면 필터에서 사용하는 리소스를 해제할 수 있습니다.

FilterConfig 인터페이스

필터를 구성할 때 사용자는 필터에 대한 일부 초기화 매개변수를 구성할 수 있습니다. 웹 컨테이너가 필터 개체를 인스턴스화하고 해당 초기화 메서드를 호출하면 필터 초기화 매개변수는 다음과 같습니다. 캡슐화됨 filterConfig 개체가 전달됩니다. 따라서 개발자가 필터를 작성할 때 filterConfig 객체의 메소드를 통해 다음 내용을 얻을 수 있습니다:

String getFilterName();//得到filter的名称。 String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null. Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 public ServletContext getServletContext();//返回Servlet上下文对象的引用。
로그인 후 복사

필터 사용 사례

필터를 사용하여 사용자 로그인 보안 제어 확인

이전 단락 사용자가 시스템에서 로그아웃한 후에도 URL에 따라 주소 표시줄로 이동하면 시스템 응답 페이지에 들어갈 수 있습니다. 확인해보니 사용자 로그인을 확인하기 위해 요청이 필터링되지 않은 것으로 나타났습니다. 문제를 해결하려면 필터를 추가하세요!

먼저 web.xml에서

<filter>
    <filter-name>SessionFilter</filter-name>
    <filter-class>com.action.login.SessionFilter</filter-class>
    <init-param>
        <param-name>logonStrings</param-name><!-- 对登录页面不进行过滤 -->
        <param-value>/project/index.jsp;login.do</param-value>
    </init-param>
    <init-param>
        <param-name>includeStrings</param-name><!-- 只对指定过滤参数后缀进行过滤 -->
        <param-value>.do;.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>redirectPath</param-name><!-- 未通过跳转到登录界面 -->
        <param-value>/index.jsp</param-value>
    </init-param>
    <init-param>
        <param-name>disabletestfilter</param-name><!-- Y:过滤无效 -->
        <param-value>N</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>SessionFilter</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>
로그인 후 복사

를 구성한 다음 FilterServlet.java:

package com.action.login;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;/**
 *    判断用户是否登录,未登录则退出系统
 */public class SessionFilter implements Filter {    public FilterConfig config;    public void destroy() {        this.config = null;
    }    public static boolean isContains(String container, String[] regx) {        boolean result = false;        for (int i = 0; i < regx.length; i++) {            if (container.indexOf(regx[i]) != -1) {                return true;
            }
        }        return result;
    }    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest hrequest = (HttpServletRequest)request;
        HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper((HttpServletResponse) response);

        String logonStrings = config.getInitParameter("logonStrings");        // 登录登陆页面
        String includeStrings = config.getInitParameter("includeStrings");    // 过滤资源后缀参数
        String redirectPath = hrequest.getContextPath() + config.getInitParameter("redirectPath");// 没有登陆转向页面
        String disabletestfilter = config.getInitParameter("disabletestfilter");// 过滤器是否有效

        if (disabletestfilter.toUpperCase().equals("Y")) {    // 过滤无效
            chain.doFilter(request, response);            return;
        }
        String[] logonList = logonStrings.split(";");
        String[] includeList = includeStrings.split(";");        if (!this.isContains(hrequest.getRequestURI(), includeList)) {// 只对指定过滤参数后缀进行过滤
            chain.doFilter(request, response);            return;
        }        if (this.isContains(hrequest.getRequestURI(), logonList)) {// 对登录页面不进行过滤
            chain.doFilter(request, response);            return;
        }

        String user = ( String ) hrequest.getSession().getAttribute("useronly");//判断用户是否登录
        if (user == null) {
            wrapper.sendRedirect(redirectPath);            return;
        }else {
            chain.doFilter(request, response);            return;
        }
    }    public void init(FilterConfig filterConfig) throws ServletException {
        config = filterConfig;
    }
}
로그인 후 복사

를 작성합니다. 이러한 방식으로 사용자에 대한 모든 요청을 완료할 수 있으며 사용자 로그인은 반드시 완료되어야 합니다. 이 Filter 를 통해 검증해 보세요.

한자 깨짐 방지를 위한 필터

프로젝트에서 spring 프레임워크를 사용하는 경우. 프런트엔드 JSP 페이지와 JAVA 코드에서 서로 다른 문자 집합을 인코딩에 사용하는 경우 양식으로 제출한 데이터나 업로드/다운로드한 중국어 이름 파일이 깨질 수 있으므로 이 필터를 사용할 수 있습니다.

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name><!--用来指定一个具体的字符集-->
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name><!--true:无论request是否指定了字符集,都是用encoding;false:如果request已指定一个字符集,则不使用encoding-->
        <param-value>false</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>
로그인 후 복사

Spring+Hibernate의 OpenSessionInViewFilter는 세션 전환을 제어합니다

hibernate+spring을 함께 사용할 때lazy=true(lazy loading)로 설정하면 데이터를 읽을 때 상위 항목을 읽은 후 데이터를 사용하면 최대 절전 모드는 자동으로 세션을 닫습니다. 이와 관련된 데이터 및 하위 데이터를 사용하려는 경우 시스템은 spring에서 제공하는 OpenSessionInViewFilter 필터를 사용해야 합니다. .

OpenSessionInViewFilter는 요청이 모든 페이지를 클라이언트에 보낼 때까지 주로 Session 상태를 유지하고, 요청이 완료될 때까지 세션을 닫지 않으므로 로딩 지연으로 인해 발생하는 문제를 해결합니다.

참고: OpenSessionInViewFilter 구성은 struts2 구성 앞에 작성되어야 합니다. Tomcat 컨테이너가 필터를 순서대로 로드하기 때문에 구성 파일이 struts2 필터 구성을 먼저 작성한 다음 OpenSessionInViewFilter 필터 구성을 작성하면 로드 순서로 인해 작업이 데이터를 얻을 때 세션 연결이 끊어집니다.

<filter><!-- lazy loading enabled in spring -->
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    <init-param>
        <param-name>sessionFactoryBeanName</param-name><!-- 可缺省。默认是从spring容器中找id为sessionFactory的bean,如果id不为sessionFactory,则需要配置如下,此处SessionFactory为spring容器中的bean。 -->
        <param-value>sessionFactory</param-value>
    </init-param>
    <init-param>
        <param-name>singleSession</param-name><!-- singleSession默认为true,若设为false则等于没用OpenSessionInView -->
        <param-value>true</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <url-pattern>*.do</url-pattern></filter-mapping>
로그인 후 복사

Struts2 web.xml 구성

프로젝트에서 Struts2를 사용하려면 web.xml에 필터를 구성하여 요청을 가로채서 처리를 위해 Struts2 Action으로 전송해야 합니다.

참고: Struts2 버전이 2.1.3 이전인 경우 필터는 org.apache.struts2.dispatcher.FilterDispatcher를 사용합니다. 그렇지 않으면 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter를 사용하십시오. Struts2.1.3부터 ​​ActionContextCleanUp 필터는 폐기되고 해당 기능은 StrutsPrepareAndExecuteFilter 필터에 포함됩니다.

세 가지 초기화 매개변수 구성:

구성 매개변수: 로드할 구성 파일을 지정합니다. 쉼표로 구분되었습니다.

actionPackages 매개변수: Action 클래스가 위치한 패키지 공간을 지정합니다. 쉼표로 구분되었습니다.

configProviders 매개변수: ConfigurationProvider 인터페이스 클래스를 구현해야 하는 사용자 정의 구성 파일 공급자입니다. 쉼표로 구분되었습니다.

<!-- struts 2.x filter --><filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class></filter><filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.do</url-pattern></filter-mapping>
로그인 후 복사

Filter in Java에 대한 자세한 설명과 관련 글은 PHP 중국어 홈페이지를 참고해주세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿