위로
아래
필터
필터(filter)
//filter.class 파일
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class ~Filter implements Filter {
@Override
public void init(FilterConfig fc) throws ServletException{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
}
@Override
public void destroy() {
}
}
- HTTP 요청과 응답을 변경할 수 있는 재사용 가능한 클래스
- 클라이언트와 서버 사이에서 request와 response 객체를 먼저 받아 사전, 사후 작업 등 공통적으로 필요한 부분을 처리하는 것
- 클라이언트의 요청이 웹 서버의 서블릿, JSP, HTML 페이지 같은 정적 리소스에 도달하기 전과, 정적 리소스에서 클라이언트로 응답하기 전에 필요한 전처리를 가능하게 함.
- 최종 자원과 클라이언트로 가는 응답(response) 사이에 위치하여, 최종 자원의 요청 결과를 알맞게 변경 가능.
- 클라이언트의 요청을 수행하지 않고, 다른 자원의 결과를 클라이언트에게 전송할 수도 있다 (사용자 인증이나 권한 검사 등에 사용)
필터 체인 (filter chain)
- 클라이언트와 정적 리소스 사이에 여러 개의 필터로 이루어진 필터 체인을 제공
사용 범위
- 사용자 인증
- 캐싱 필터
- 자원 접근에 대한 로깅
- 응답 데이터 변환 (HTML변환, 응답 헤더 변환, 데이터 암호화 등)
- 공통 기능 실행
web.xml 이용 Filter 구현
- ~filter.class 파일을 어떤 어떤 리소스에 적용할 건지 JSP 컨테이너에 알려주기 위해 web.xml에 적어놓는다.
- web.xml에 선언하면, 계속 만들 필요 없이 한 번만 만든 클래스를 재사용할 수 있다.
- <filter> 태그와 <filter-mapping>태그 사용
- web.xml 파일에 여러 개의 필터가 설정되어 있으면 선언된 순서대로 실행
// 기본형
<filter>
<filter-name>Filter01</filter-name>
<filter-class>filter.AuthenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/jspEx/Filter01Process.jsp</url-pattern>
</filter-mapping>
태그 종류
- <filter> 태그 : 웹 어플리케이션에서 사용할 필터 지정
- <filter-name> 태그 : 필터의 이름 (filter와 filter-mapping에 들어가는 이름이 같아야 한다)
- <filter-mapping> 태그 : 특정 자원에 대해 어떤 필터를 사용할지 지정
- <filter-class> 태그 : 필터가 있는 위치
- <url-pattern>태그 : 클라이언트가 요청한 특정 URI에 대해서 필터링할 때 사용
- <init-param> 태그 : 필터를 초기화할 때(init()필터를 호출할 때) 전달할 파라미터를 설정
- <servlet-name>태그 : url-pattern 태그 대신에 사용할 수 있으며, 특정 서블릿에 대한 요청에 대해서 필터를 적용.
- <dispatcher>태그 : 필터가 적용되는 시점을 설정 가능 (filter-mapping 태그의 안 쪽에 위치)
- <dispatcher>REQUEST</dispatcher> : 클라이언트의 요청인 경우에 필터를 적용 (기본값)
- <dispatcher>FORWARD</dispatcher> : forwaed()를 통해서 제어 흐름을 이동하는 경우에 필터 적용
- <dispatcher>INCLUDE</dispatcher> : include()를 통해서 포함되는 경우에 필터 적용
다른 방법들
- @WebFilter 애노테이션 이용
- Filter 인터페이스 이용
Filter 인터페이스
Filter 인터페이스
- 클라이언트와 서버의 리소스 사이에 위치한 필터의 기능을 제공하기 위해 자바 클래스로 구현해야 함
- Filter 인터페이스 메소드 종류
- init () : 필터 인스턴스의 초기화 메소드
- doFilter () : 필터 기능을 작성하는 메소드
- destroy () : 필터 인스턴스의 종료 전에 호출되는 메소드
init() 메소드
@Override
public void init(FilterConfig fc) throws ServletException{}
- JSP 컨테이너 내에서 초기화 작업을 수행할 필터 인스턴스를 생성한 후 한 번만 호출
- JSP 컨테이너에 의해 호출되어 필터의 서비스가 시작되고 있음을 나타냄
- filterConfig
- init 메소드의 매개변수로 전달되는 객체.
- web.xml에서 <init-param> 태그를 통해 작성해준 정보들과, ServletContext에 대한 참조를 가지고 있다.
- getFilterName() : 필터 등록시 지정한 필터명 반환
- getInitParameter(String name) : web.xml에서 <init-param>의 <param-name>을 매개변수로 넣으면, <param-value>로 등록한 값이 반환. 없으면 null 리턴.
- getServletContext() : 필터가 속해있는 웹 어플리케이션의 ServletContext를 리턴
- getInitParameterNames() : 필터에 설정되어 있는 초기화 설정값들의 설정명을 Enumeration으로 리턴. (설정명들을 담은 목록 리턴)
doFilter() 메소드
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {}
- JSP 컨테이너가 필터를 리소스에 적용할 때마다 호출하는 메소드
- init() 메소드 후에 호출되며, 필터가 어떤 기능을 수행할 필요가 있을 때마다 호출
- 매개변수 ServletRequest 객체 : 체인을 따라 전달하는 요청
- 매개변수 ServletResponse 객체 : 체인을 따라 전달할 응답
- 매개변수 FilterChain 객체 : 체인에서 다음 필터를 호출하는데 사용
- 만약 호출 필터가 체인의 마지막 필터이면 체인의 끝에서 리소스를 호출
destroy() 메소드
- 필터 인스턴스를 종료하기 전에 호출하는 메소드
- 필터의 수명 동안 한 번만 호출
- JSP 컨테이너가 필터 인스턴스를 삭제하기 전에 청소 작업을 수행하는데 사용. (필터로 열린 리소스를 모두 닫을 수 있는 방법)
@Override
public void destroy() {}
예시
인코딩 필터
더보기
// web.xml 파일에 인코딩 필터 코드
<filter>
<filter-name>Encoding Filter</filter-name>
<filter-class>filter.CommonEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
// CommonEncodingFilter.class 파일
package filter;
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;
public class CommonEncodingFilter implements Filter {
/**
* 인코딩을 수행할 인코딩 캐릭터 셋 지정
*/
private String encoding = null;
/**
* 필터 설정 관리자
*/
protected FilterConfig filterConfig = null;
/**
* @return
*/
public FilterConfig getFilterConfig() {
return filterConfig;
}
/**
* @param cfg
*/
public void setFilterConfig(FilterConfig cfg) {
filterConfig = cfg;
}
@Override
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (request.getCharacterEncoding() == null) {
if (encoding != null) {
request.setCharacterEncoding(encoding);
}
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
this.encoding = filterConfig.getInitParameter("encoding");
}
}
null값 입력 오류 필터
더보기
//web.xml 파일에 null값 입력 오류 필터 코드
<filter>
<filter-name>Filter01</filter-name>
<filter-class>filter.AuthenFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/jspEx/Filter01Process.jsp</url-pattern>
</filter-mapping>
// AutenFilter.class 파일
package filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class AuthenFilter implements Filter {
@Override
public void init(FilterConfig fc) throws ServletException{
System.out.println("Filter01 초기화");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Filter01.jsp 수행...");
String name = request.getParameter("name");
if(name == null || name.equals("")) {
response.setContentType("text/html; charset=UTF-8");
PrintWriter writer = response.getWriter();
String msg = "입력된 name값은 null입니다.";
writer.println(msg);
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("Filter01 해제");
}
}
<!-- 테스트용 Filter01.jsp 파일 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="Filter01Process.jsp" method="post">
<p>이름 : <input type="text" name="name"></p>
<p><input type="submit" value="전송"></p>
</form>
</body>
</html>
<!-- 처리페이지 Filter01Process.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String name = request.getParameter("name");
%>
<p>입력된 name값 : <%=name %></p>
</body>
</html>
관리자 아이디 비밀번호 필터
더보기
// web.xml 파일에 관리자 아이디 비밀번호 필터 코드
<filter>
<filter-name>Filter02</filter-name>
<filter-class>filter.InitParamFilter</filter-class>
<init-param>
<param-name>param1</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>1234</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Filter02</filter-name>
<url-pattern>/jspEx/Filter02Process.jsp</url-pattern>
</filter-mapping>
// InitParamFilter.class 파일
package filter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class InitParamFilter implements Filter {
private FilterConfig fc = null;
@Override
public void init(FilterConfig fc) throws ServletException{
System.out.println("Filter02 초기화");
this.fc = fc;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("Filter02 수행");
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
String param1 = fc.getInitParameter("param1");
String param2 = fc.getInitParameter("param2");
String msg;
response.setContentType("text/html; charset=UTF-8");
PrintWriter writer = response.getWriter();
if(id.equals(param1) && passwd.equals(param2)) {
msg="관리자 로그인 성공";
} else {
msg = "관리자 로그인 실패";
}
writer.println(msg);
//다음 필터로 가라 chain연결
chain.doFilter(request, response);
}
@Override
public void destroy() {
System.out.println("Filter02 해제");
}
}
<!-- 테스트용 Filter02.jsp 파일 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="Filter02Process.jsp" method="post">
<p>아이디 : <input type="text" name="id"></p>
<p>비밀번호 : <input type="text" name="passwd"></p>
<p><input type="submit" value="전송"></p>
</form>
</body>
</html>
<!-- 로그인 처리 페이지 Filter02Process.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
%>
<p>입력된 id값 : <%=id %></p>
<p>입력된 passwd값 : <%=passwd %></p>
</body>
</html>
로그 파일 생성 예시
더보기
// web.xml 파일에 코드
<filter>
<filter-name>Filter02_2</filter-name>
<filter-class>filter.LogFileFilter</filter-class>
<init-param>
<param-name>fileName</param-name>
<param-value>D:\\Ecom_Work_js\\logs\monitor.log</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Filter02_2</filter-name>
<url-pattern>/jspEx/Filter02Process.jsp</url-pattern>
</filter-mapping>
//로그 파일 필터
package filter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class LogFileFilter implements Filter {
PrintWriter writer;
@Override
public void init(FilterConfig fc) throws ServletException{
String fileNm = fc.getInitParameter("fileName");
if(fileNm==null)
throw new ServletException("로그 파일의 이름을 찾을 수 없습니다.");
try {
//fileName에 해당하는 파일을 가져와서 출력용 파일로 오픈 하기
writer = new PrintWriter(new FileWriter(fileNm, true), true);
} catch(IOException e) {
throw new ServletException("로그 파일을 열 수 없습니다.");
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
writer.printf("현재 일시 : %s %n", getCurrentTime());
String clientAddr = request.getRemoteAddr();
writer.printf("클라이언트 주소 : %s %n", clientAddr);
chain.doFilter(request, response);
String contentType = response.getContentType();
writer.printf("문서의 콘텐츠 유형 : %s %n", contentType);
writer.println("--------------------------------");
}
private Object getCurrentTime() {
DateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
return format.format(calendar.getTime());
}
@Override
public void destroy() {
// 오픈된 파일을 반드시 닫기 위해 실행
writer.close();
}
}
<!-- 테스트용 Filter02.jsp 파일 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="Filter02Process.jsp" method="post">
<p>아이디 : <input type="text" name="id"></p>
<p>비밀번호 : <input type="text" name="passwd"></p>
<p><input type="submit" value="전송"></p>
</form>
</body>
</html>
<!-- 로그인 처리 페이지 Filter02Process.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String id = request.getParameter("id");
String passwd = request.getParameter("passwd");
%>
<p>입력된 id값 : <%=id %></p>
<p>입력된 passwd값 : <%=passwd %></p>
</body>
</html>