English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Filter 개요
Filter는 또한 필터라고 불리며, Servlet 기술에서 가장 실용적인 기술 중 하나입니다. 웹 개발자는 Filter 기술을 통해 웹 서버가 관리하는 모든 웹 자원(예: Jsp, Servlet, 스태틱 이미지 파일 또는 스태틱 html 파일 등)에 대해 차단을 통해 특정 기능을 구현할 수 있습니다. 예를 들어, URL 수준의 권한 접근 제어, 감사 단어 필터링, 응답 정보 압축 등의 고급 기능을 구현할 수 있습니다.
주로 사용자 요청을 사전 처리하는 데 사용되며, HttpResponse를 사후 처리도 할 수 있습니다. Filter를 사용하는 전체流程: Filter는 사용자 요청을 사전 처리한 후, 요청을 Servlet에 넘겨 처리하고 응답을 생성한 다음, Filter는 서버 응답을 사후 처리합니다.
Filter 기능
HttpServletRequest가 Servlet에 도달하기 전에 클라이언트의 HttpServletRequest를 차단합니다. 필요에 따라 HttpServletRequest를 확인하고도 HttpServletRequest Header와 데이터를 수정할 수 있습니다.
HttpServletResponse가 클라이언트에 도달하기 전에 HttpServletResponse를 차단합니다. 필요에 따라 HttpServletResponse를 확인하고도 HttpResponseHeader와 데이터를 수정할 수 있습니다.
Filter를 통해 차단 기능을 어떻게 구현할 수 있는지
Filter 인터페이스에는 doFilter 메서드가 있습니다. 개발자가 Filter를 작성하고 특정 웹 자원에 대한 접근을 차단할 설정을 구성한 후, 웹 서버가 웹 자원의 service 메서드를 호출하기 전에 항상 filter의 doFilter 메서드를 호출합니다. 따라서 이 메서드 내에서 코드를 작성하면 다음과 같은 목적을 달성할 수 있습니다:
목표 자원 호출 전에 일단 코드를 실행합니다.
목표 자원(사용자가 웹 자원에 접근할지 여부)을 호출할지 여부.
웹 서버가 doFilter 메서드를 호출할 때, filterChain 객체를 전달합니다. filterChain 객체는 filter 인터페이스에서 가장 중요한 객체 중 하나로, doFilter 메서드도 제공합니다. 개발자는 필요에 따라 이 메서드를 호출할지 여부를 결정할 수 있으며, 이 메서드를 호출하면 웹 서버가 웹 자원의 service 메서드를 호출하게 되어 웹 자원이 접근됩니다. 그렇지 않으면 웹 자원이 접근되지 않습니다.
Filter 개발 두 단계 취
Filter 인터페이스를 구현한 java 클래스를 작성하고, 그의 doFilter 메서드를 구현합니다。
web.xml 파일에서 작성한 필터 클래스를 등록하고, 그가 차단할 수 있는 자원을 설정합니다。
web.xml 설정 각 노드 소개:
Filter 체인
한 웹 애플리케이션에서는 여러 Filter를 개발하고, 이 필터들은 Filter 체인으로 组合됩니다.
웹 서버는 web.xml 파일에서 필터가 등록된 순서에 따라哪个 필터를 먼저 호출할지 결정합니다. 첫 번째 필터의 doFilter 메서드가 호출될 때, 웹 서버는 필터 체인을 대표하는 FilterChain 객체를 생성하고 해당 메서드에 전달합니다. doFilter 메서드에서 개발자가 FilterChain 객체의 doFilter 메서드를 호출하면, 웹 서버는 FilterChain 객체에 필터가 더 있는지 확인하고, 있다면 다음 필터를 호출합니다.2필터가 없으면, 목표 자원을 호출합니다.
Filter의 생명주기
public void init(FilterConfig filterConfig) throws ServletException;//초기화
우리가 작성한 Servlet 프로그램과 마찬가지로, 필터의 생성과 소멸은 WEB 서버가 책임합니다. 웹 애플리케이션이 시작될 때, 웹 서버는 필터의 인스턴스 객체를 생성하고, init 메서드를 호출하여 web.xml 설정을 읽고, 객체의 초기화 기능을 완료하여 후속 사용자 요청에 대한 차단 준비를 합니다. 개발자는 init 메서드의 파라미터를 통해 현재 필터 구성 정보를 대표하는 FilterConfig 객체를 얻을 수 있습니다.
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;//요청을 차단합니다
이 방법은 실제 필터링 작업을 완료합니다. 고객이 필터와 연결된 URL에 접근 요청을 보낼 때, Servlet 필터는 먼저 doFilter 메서드를 실행합니다. FilterChain 파라미터는 후속 필터에 접근하기 위해 사용됩니다.
public void destroy();//소멸
Filter 객체가 생성되면 메모리에 남아 있으며, 웹 애플리케이션이 제거되거나 서버가 중지될 때까지 파괴됩니다. Filter 객체가 Web 컨테이너에서 해제되기 전에 호출됩니다. 이 메서드는 Filter의 생명주기를 통해 단 한 번만 실행됩니다. 이 메서드에서는 필터가 사용하는 자원을 해제할 수 있습니다.
FilterConfig 인터페이스
필터를 설정할 때 사용자는 필터에 초기화 파라미터를 설정할 수 있습니다. 웹 컨테이너가 Filter 객체를 인스턴스화할 때, init 메서드를 호출하면 필터 초기화 파라미터를 포함한 필터 컨피그레이션 객체가 전달됩니다. 따라서 개발자는 필터를 작성할 때, filterConfig 객체의 메서드를 통해 다음과 같은 내용을 얻을 수 있습니다:
String getFilterName();//필터의 이름을 얻습니다. String getInitParameter(String name);//배포 설명서에서 지정한 이름의 초기화 파라미터의 값을 반환합니다. 존재하지 않으면 null을 반환합니다. Enumeration getInitParameterNames();//모든 초기화 파라미터 이름의 열거집합을 반환합니다. public ServletContext getServletContext();//Servlet 컨텍스트 객체의 참조를 반환합니다.
Filter 사용 예제
Filter를 사용하여 사용자 로그인 보안을 검증합니다.
최근 프로젝트 유지보수에 참여했을 때, 사용자가 시스템에서 로그아웃한 후, 주소 표시줄에서 이전 페이지에 접근했을 때, 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>/프로젝트/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을 작성합니다.
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; } }
이렇게 하면 모든 사용자 요청이 이 필터를 통해 사용자 로그인을 확인하는 것을 완료할 수 있습니다.
중국어 맥락의 변조를 방지하는 필터
프로젝트가 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>
이것이 본 문서의 모든 내용입니다. 많은 도움이 되었기를 바랍니다. 또한, 나아가는 교재에 많은 지원을 부탁드립니다.
고지사항: 본문은 인터넷에서 수집되었으며, 저작권자는 모두 소유합니다. 인터넷 사용자가 자발적으로 기여하고 업로드한 내용이며, 이 사이트는 소유권을 가지지 않으며, 인공적인 편집을 거치지 않았으며, 관련 법적 책임도 부담하지 않습니다. 저작권 위반이 의심되는 내용이 발견되면 메일을 보내 주시기 바랍니다: notice#oldtoolbag.com(메일을 보내는 경우,#을 @으로 변경하십시오. 신고하고 관련 증거를 제공하시면, 사이트가 즉시 위반 내용을 삭제합니다。)