1. 필터의 개요
필터(filter)
클라이언트와 서버 사이에서 request와 response 객체를 먼저 받아 사전/사후 작업 등 공통적으로 필요한 부분을 처리하는 것
클라이언트의 요청이 웹 서버의 서블릿, JSP, HTML 페이지 같은 정적 리소스에 도달하기 전과, 반대로 정적 리소스에서 클라이언트로 응답하기 전에 필요한 전처리를 가능하게 함
필터는 HTTP 요청과 응답을 변경할 수 있는 코드로 재사용 가능
클라이언트와 정적 리소스 사이에 여러 개의 필터로 이루어진 필터 체인을 제공하기도 함
![]() |
2. Filter 인터페이스의 구현 클래스
Filter 인터페이스
필터 기능을 구현하는 데 핵심적인 역할을 함
클라이언트와 서버의 리소스 사이에 위치한 필터의 기능을 제공하기 위해 자바 클래스로 구현해야 함
![]() |
init() 메소드

init( ) 메소드는 JSP 컨테이너 내에서 초기화 작업을 수행할 필터 인스턴스를 생성한 후 한 번만 호출
init( ) 메소드는 JSP 컨테이너에 의해 호출되어 필터의 서비스가 시작되고 있음을 나타냄
doFilter() 메소드
JSP 컨테이너가 필터를 리소스에 적용할 때마다 호출되는 메소드
init( ) 메소드 후에 호출되며, 필터가 어떤 기능을 수행할 필요가 있을 때마다 호출
첫 번째 매개변수 ServletRequest 객체는 체인을 따라 전달하는 요청이고,
두 번째 매개변수 ServletResponse 객체는 체인을 따라 전달할 응답
세 번째 매개변수 FilterChain 객체는 체인에서 다음 필터를 호출하는 데 사용 만약 호출 필터가 체인의 마지막 필터이면 체인의 끝에서 리소스를 호출
destroy() 메소드
필터 인스턴스를 종료하기 전에 호출하는 메소드
destroy( ) 메소드는 필터의 수명 동안 한 번만 호출
3. web.xml 파일의 필터 구성
web.xml 파일에 필터를 설정
필터를 사용하려면 어떤 필터가 어떤 리소스에 대해 적용되는지 JSP 컨테이너에 알려주어야 함
<filter>와 <filter-mapping> 요소를 사용
web.xml 파일에 여러 개의 필터가 설정되어 있으면 선언된 순서대로 실행
![]() |
![]() |
![]() |
<filter> 요소
<filter> 요소는 웹 애플리케이션에서 자바 필터와 매개변수를 설정하는 데 사용
<init-param> 요소
설정된 매개변수와 값을 자바 또는 JSP 코드에서 접근
위의 예에서 <init-param> 요소에 설정된 매개변수와 값을 자바 클래스에서 접근하려면 다음과 같이 작성
<filter-mapping> 요소
특정 리소스에 대해 어떤 필터를 사용할지 설정하는 데 사용
![]() |
![]() |
예제
web.xml
<!-- filter 인터페이스의 구현 클래스 -->
<filter>
<filter-name>Filter01</filter-name>
<filter-class>filter.AuthenFilter</filter-class>
</filter>
<!-- Filter01 로 연결된 필터를 사용할 요청 URL -->
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/ch12/filter01_process.jsp</url-pattern>
</filter-mapping>
<filter>
<filter-name>Filter02</filter-name>
<filter-class>filter.initParamFilter</filter-class>
<!-- param1=admin¶m2=java -->
<!-- 매개변수 = 매개변수값 ,
InitParamFilter 클래스의 init메소드로 던져짐
param1=admin¶m2=java-->
<init-param>
<param-name>param1</param-name>
<param-value>admin</param-value>
</init-param>
<init-param>
<param-name>param2</param-name>
<param-value>java</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Filter02</filter-name>
<url-pattern>/ch12/filter02_process.jsp</url-pattern>
</filter-mapping>
AuthenFilter.java
package filter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
//Filter 인터페이스를 구현한 구현 클래스
public class AuthenFilter implements Filter{
//필터 시작. 초기화
@Override
public void init(FilterConfig arg0) throws ServletException{
System.out.println("Filter01 초기화 완료...");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
System.out.println("filter01 수행");
//request{name='개동이'}
// 도는 request{namne=}
//폼페이지에서 전송된 파라미터를 전달받음
String name = request.getParameter("name"); //개똥이 or ""
//응답 메시지를 담아서 서버에서 클라이언트로 전달해줌 (response 객체활용)
if(name == null || name.equals("") ) {
//문자 인코딩
response.setCharacterEncoding("UTF-8");
//컨텐츠 유형
response.setContentType("text/html;charset=utf-8");
//메시지
PrintWriter writer = response.getWriter();
String message ="입력된 name값은 null입니다.";
writer.println(message);
return;
}
//필터가 여러개가 있을 때 request, response객체를 전달해주
chain.doFilter(request, response);
}
//필터 종료 하기 전에 호출
@Override
public void destroy() {
System.out.println("Filter01 해제..");
}
}
initParamFilter.java
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 initParamFilter implements Filter {
//프로퍼티
private FilterConfig filterConfig = null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter02 초기화..");
this.filterConfig = filterConfig;
}
/*
요청URI : filter02_process.jsp
요청파라미터 : {id=admin,passwd=java}
요청방식 : post
*/
@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");
System.out.println("id : " + id + ", passwd : " + passwd);
}
@Override
public void destroy() {
System.out.println("Filter02 해제..");
}
}
filter01.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>filter</title>
</head>
<body>
<!-- 폼페이지
요청URI : /ch12/filter01_process.jsp
요청파라미터 : {name=개똥이}
요청방식 : post
-->
<form action="/ch12/filter01_process.jsp" method="post">
<p>이름 : <input type="text" name="name" placeholder="이름을 입력하세요"/>
<p><input type="submit" value="전송"/></p>
</form>
</body>
</html>
filter01_process.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<!-- 폼페이지
요청URI : /ch12/filter01_process.jsp
요청파라미터 : {name=개똥이}
요청방식 : post
-->
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
%>
<p>입력된 name 값 :<%=name%><p>
</body>
</html>
filter02.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Filter</title>
</head>
<body>
<!-- 폼페이지
요청URI : /ch12/filter02_process.jsp
요청파라미터 : {id=admin, passwd=java}
요청방식 : post
-->
<form action="/ch12/filter02_process.jsp" method="post">
<p>아이디 : <input type="text" name="id" placeholder="아이디" required/></p>
<p>비밀번호 : <input type="text" name="passwd" placeholder="비밀번호" required/></p>
<p><input type="submit" value="전송"/></p>
</form>
</body>
</html>
filter02_process.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
/*
요청URI : filter02_process.jsp
요청파라미터 : {id=admin,passwd=java}
요청방식 : post
*/
String id= request.getParameter("id"); //admin
String passwd = request.getParameter("passwd"); //java
%>
<p>입력된 id값 : <%=id %></p>
<p>입력된 pw값 : <%=passwd%></p>
</body>
</html>
LogFileFilter.java
package filter;
import java.io.File;
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;
import javax.servlet.http.HttpServletRequest;
public class LogFileFilter implements Filter {
//파일로 만들어야 하므로 파일객체를 전역변수 형태로 선언
PrintWriter writer;
//초기화
/*
<init-param>
<param-name>filename</param-name>
<param-value>c:\\logs\\webmarket.log</param-value>
</init-param>
알기쉽게 설명 : ?filename=c:\\logs\\webmarket.log
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String filename =
filterConfig.getInitParameter("filename"); //c:\\logs\\webmarket.log
//로그를 파일로 저장하기 위해 초기화 작업 수행
//filename => c:\\logs\\webmarket.log
// String filename = "c:\\logs\\webmarket.log";
try {
//FileWriter(String fileName, boolean true/false)
//1) true : 기존 내용에 새로운 내용이 추가(append)
//2) false : 기존 내용을 지우고 덮어쓰기(overwrite)
//PrintWriter(출력대상, boolean true/false)
//1) true : Auto flush -> writer.flush()를 생략함
//2) false : Auto flush 안함
this.writer = new PrintWriter(new FileWriter(filename,true),true);
//monitor.log파일이 없으면 자동생성
//이렇게 하겠다 라고 설계
File file = new File(filename);
if(!file.exists()) { // 설계상의 파일이 실제로는 없으면..
//설계대로 파일을 생성
file.createNewFile();
writer.println(file.getAbsolutePath() + "파일이 생성 되었습니다.");
}else {// monitor.log 파일이 있다면..
System.out.println(file.getAbsolutePath() + "파일이 생성되어 있습니다.");
}
} catch (IOException e) {
throw new ServletException("로그 파일을 열 수 없습니다");
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
writer.println("접속한 클라이언트 IP : " + request.getRemoteAddr());
//시스템 현재시간(시작시간)
long start = System.currentTimeMillis();
writer.println("접근 가능한 경로 : " + getURLPath(request));
writer.println("요청 처리 시작 시각 : " + getCurrentTime());
//필터가 연속적으로 있다면 다음 필터로 제어 및 요청 (request)/ 응답(reqponse) 정보를 넘겨줌
chain.doFilter(request, response);
//시스쳄 현재 시간(종료시간)
long end = System.currentTimeMillis();
writer.println("요청 처리 종료 시각 : " + getCurrentTime());
writer.println("요청 처리 소요시간 : " + (end - start) + "ms"); /// 1000분의 1초
writer.println("=========================");
}
@Override
public void destroy() {
// 파일 객체를 닫아줌. 메모리에서 제거
writer.close();
}
//접근한 URL 경로 리턴 메소드
// http://localhost/ch11/readParameterNoErrorPage.jsp?name=개똥이
private String getURLPath(ServletRequest request) {
//HttpServletRequest 인터페이스 는 ServletRequest 인터페이스를 상속받음
HttpServletRequest req;
//currentPath : URL경로 => http://localhost/ch11/readParameterNoErrorPage.jsp
String currentPath = "";
//queryString : 요청파라미터 => name=개똥이
String queryString = "";
//instanceOf 연산자는 객체가 어떤 클래스인지, 어떤 클래스를 상속받았는지 확인하는 데 사용됨
if(request instanceof HttpServletRequest) {
//자식 = (cast)부모
req = (HttpServletRequest)request;
currentPath = req.getRequestURI();//http://localhost/ch11/readParameterNoErrorPage.jsp
System.out.println("currentPath : " + currentPath);
queryString = req.getQueryString();//name=개똥이
System.out.println("queryString : " + queryString);
//삼항연산자
queryString = queryString == null?"":"?"+queryString;
}
//http://localhost/ch11/readParameterNoErrorPage.jsp?name=개똥이
return currentPath + queryString;
}//end getURLPath()
//현재 시간을 얻어오는 메소드
private String getCurrentTime() {
//2023/03/31 17:29:12
DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
//캘린더 객체 생성(싱글톤 : 메모리에 1번 생성하고 전역변수처럼 사용)
Calendar calendar = Calendar.getInstance();
//톰켓서버에서 제공해주는 시스템 현재 시간을 구해서 캘린더 객체에 세팅
calendar.setTimeInMillis(System.currentTimeMillis());
//2023/03/31 17:29:12 이러한 포맷을 준수하면서 리턴
return formatter.format(calendar.getTime());
}
}
filter03.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Filter</title>
</head>
<body>
<!-- 폼페이지
요청URI : /ch12/filter03_process.jsp
요청파라미터 : {id=admin, passwd=java}
요청방식 : post
-->
<form action="/ch12/filter03_process.jsp" method="post">
<p>아이디 : <input type="text" name="id" placeholder="아이디" required/></p>
<p>비밀번호 : <input type="text" name="passwd" placeholder="비밀번호" required/></p>
<p><input type="submit" value="전송"/></p>
</form>
</body>
</html>
filter03_process.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<%
request.setCharacterEncoding("UTF-8");
/*
요청URI : filter03_process.jsp
요청파라미터 : {id=admin,passwd=java}
요청방식 : post
*/
String id= request.getParameter("id"); //admin
String passwd = request.getParameter("passwd"); //java
%>
<p>입력된 id값 : <%=id %></p>
<p>입력된 pw값 : <%=passwd%></p>
</body>
</html>
참고파일
'JSP 웹 프로그래밍 > 수업내용' 카테고리의 다른 글
[JSP 웹 프로그래밍] 쿠키(cookie) (0) | 2024.07.18 |
---|---|
[JSP 웹 프로그래밍] 세션(session) (0) | 2024.07.16 |
[JSP 웹 프로그래밍] 예외처리 (0) | 2024.07.12 |
[JSP 웹 프로그래밍] 예외처리 (0) | 2024.07.12 |
[JSP 웹 프로그래밍] 시큐리티 (0) | 2024.07.10 |