.jsp 연습하기 - 필터

오늘·2021년 5월 17일
0

웹 페이지 연습

목록 보기
15/35

필터

  • 클라이언트와 서버 사이에서 request와 response 객체를 먼저 받아 사전/사후 작업 과 같은.. 공통적으로 필요한 부분을 처리하는 것
  • 정적 리소스에서 클라이언트로 응답하기 전에 필요한 전처리를 가능하게 한다.
  • 필터는 http 요청과 응답을 변경할 수 있는 코드로 재사용이 가능
  • 클라이언트와 정적 리소스 사이에 여러 개의 필터로 이루어진 필터 체인을 제공하기도 한다.

Filter 인터페이스

  • 필터 기능을 구현하는 데 핵심적인 역할을 한다.
  • 클라이언트와 서버의 리소스 사이에 위치한 필터의 기능을 제공하기 위해서는 '자바 클래스'로 구현해야 한다.
import javax.servlet.Filter;

public class 클래스 이름 implements Filter {
	(생략)
}
Filter 인터페이스 메소드의 종류
메소드 설명
int(...) 필터 인스턴스의 초기화 메소드
doFilter(...) 필터 기능을 작성하는 메소드
destroy() 필터 인스턴스의 종료 전에 호출되는 메소드

init() 메소드

JSP 컨테이너가 필터를 초기화할 때 호출되는 메소드 사용예

@Override
public void init(FilterConfig filterConfig) throws ServletException{
	system.out.println("필터 초기화");
}

doFilter() 메소드

JSP 컨테이너가 필터를 리소스에 적용할 때마다 호출되는 메소드
init( ) 메소드 후에 호출되며, 필터가 어떤 기능을 수행할 필요가 있을 때마다 호출
첫 번째 매개변수 ServletRequest 객체는 체인을 따라 전달하는 요청이고,
두 번째 매개변수 ServletResponse 객체는 체인을 따라 전달할 응답
세 번째 매개변수 FilterChain 객체는 체인에서 다음 필터를 호출하는 데 사용


destroy() 메소드

  • 필터 인스턴스를 종료하기 전에 호출하는 메소드
  • JSP 컨테이너가 필터 인스턴스를 삭제하기 전에 청소 작업을 수행하는 데 사용되며, 이는 필터로 열린 리소스를 모두 닫을 수 있는 방법
  • destroy( ) 메소드는 필터의 수명 동안 한 번만 호출한다.
메소드 사용 예
@Override
public void destroy() {
	System.out.println("필터 해제");
}

web.xml 파일에 필터를 설정

  • 필터를 사용하려면 어떤 필터가 어떤 리소스에 대해 적용되는 지 jsp 컨테이너에 알려줘야 한다.
  • web.xml 파일에 여러개의 필터가 설정되어 있으면 선언된 순서대로 실행된다.

1. 필터 내용을 자바 코드로 작성

src -> ch12.com.filter 폴더에 AuthenFliter 파일 생성

package ch12.com.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 AuthenFliter implements Filter {
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		System.out.println("Filter01 초기화 하는 부분-");
	}
	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
			throws IOException, ServletException {
		System.out.println("Filter01.jsp 수행하는 부분-");
	}
	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		Filter.super.destroy();
	}
}
  1. doFilter 부분에서
public void doFilter
	(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)

부분의 arg0, arg1, arg2 부분을

public void doFilter
	(ServletRequest request, ServletResponse response,
    			FilterChain filterChain)
이와 같이 변경해준다.
  1. 걸러줄 내용을 설정
System.out.println("Filter01.jsp 수행하는 부분-");
// 이름을 받을 건데
String name = request.getParameter("name");
// 만약 이름이 비워져있다면
if(name == null || name.equals("")) {
	// 문자 셋 설정해주고
	response.setCharacterEncoding("utf-8");
	response.setContentType("text/html); charset=utf-8");
	// 출력해준다.
	PrintWriter writer = response.getWriter();
	String message = "name 입력이 없습니다";
	writer.println(message);
	return;
}
// 만약 null 이 아니라면 값을 보내줄것이다.
filterChain.doFilter(request, response);

2. WEB-INF의 web.xml

  1. 필터 이름, 필터 내용이 작성된 파일 연결
	<filter>
		<filter-name>Filter01</filter-name>
		<!-- 필터 내용이 작성된 자바 파일을 적어주기 -->
		<filter-class>ch12.com.filter.AuthenFliter</filter-class>
	</filter>
  1. 필터 매핑
	<filter-mapping>
		<filter-name>Filter01</filter-name>
		<!-- 필터를 적용할 파일 -->
		<url-pattern>/Ch12/1_filter_process.jsp</url-pattern>
	</filter-mapping>
</web-app>

3. 클라이언트 쪽 jsp 작성

<body>
	<p> 1_Filter.jsp 클라이언트 쪽 폼태그 </p>
	<form method="post" action="1_filter_process.jsp" >
		<p> 이름 : <input type="text" name="name">
		<input type="submit" value="전송">
	</form>
</body>

4. 서버쪽 jsp 파일 작성

<body>
	<p> 서버쪽 코드 </p>
	<%
		String name = request.getParameter("name");
	%>
	<p> 입력된 이름은 : <%= name %>
</body>

5. 실행 결과

  1. 첫 실행화면 : 이름 받는 폼태그

  2. 이름을 제대로 입력 시

  3. 이름을 공백으로 입력 시

console 부분을 보면 이런식으로 init을 불러와 필터처리를 수행 중이라는 걸 시각적으로 확인 할 수 있다.

Filter01 초기화 하는 부분-
5월 13, 2021 12:52:29 오후 org.apache.coyote.AbstractProtocol start
정보: 프로토콜 핸들러 ["http-nio-4040"]을(를) 시작합니다.
5월 13, 2021 12:52:29 오후 org.apache.catalina.startup.Catalina start
정보: 서버가 [10840] 밀리초 내에 시작되었습니다.
Filter01.jsp 수행하는 부분-
Filter01.jsp 수행하는 부분-

필터 처리로 매개변수와 값을 전달받아 로그인 인증 처리

  1. web.xml
	<filter>
		<filter-name>Filter0</filter-name>
		<!-- 필터 내용이 작성된 자바 파일을 적어주기 -->
		<filter-class>ch12.com.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>/Ch12/2_filter_process.jsp</url-pattern>
	</filter-mapping>
</web-app>
  1. 값 보내는 filter.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<!DOCTYPE html>
<html>
<head>

<title>Insert title here</title>
</head>
<body>
	<p> 필터 처리로 매개변수와 값을 전달받아 로그인 인증 처리하기</p>
	-클라이언트 쪽 폼
	<hr>
	<form action="2_filter_process.jsp" method="post" >
		<p> 로그인 : <input type="text" name="id">
		<p> 비밀번호 : <input type="password" name="pw">
		<input type="submit" value="로그인" >
	</form>
</body>
</html>
  1. 값 받는 process.jsp
<title>Insert title here</title>
</head>
<body>
	<p> 필터 처리로 매개변수와 값을 전달받아 로그인 인증 처리하기</p>
	-응답보는 서버 쪽
	<hr>
	<%
		String id = request.getParameter("id");
		String pw = request.getParameter("pw");
		
		out.print("입력된 id 값 : " + id);
		out.print("입력된 pw 값 : " + pw);
	%>
	
	정상처리 되었습니다.
</body>
</html>
  1. filter.java
package ch12.com.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 filterConfig = null;
   
   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
      System.out.println("Filter02 초기화...");
      this.filterConfig = filterConfig;
      
   }
   @Override
   public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
         throws IOException, ServletException {
      System.out.println("Filter02 수행...");
      String id = request.getParameter("id");
      String password = request.getParameter("pw");
      
      String param1 = filterConfig.getInitParameter("param1");
      String param2 = filterConfig.getInitParameter("param2");
      
      String message;
      
      response.setCharacterEncoding("UTF-8");
      response.setContentType("text/html; charset=UTF-8");
      PrintWriter writer = response.getWriter();
      
      if(id.equals(param1)  && password.equals(param2))
         message = "로그인 성공했습니다";
      else
         message ="로그인 실패했습니다.";
      writer.println(message);
      
      filterChain.doFilter(request, response);
      
   }
   @Override
   public void destroy() {
      System.out.println("Filter02 해제 ...");
   }
}

필터에 작성한

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

이 아이디(admin)와 비밀번호(1234) 를 입력 받아야 로그인 성공했습니다 라고 나온다. 다른 아이디/비밀번호 입력시 로그인 실패했습니다


웹 페이지를 이용하여 필터로 로그 기록하기

  1. 필터 작성하기
package ch12.com.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 filterConfig) throws ServletException {
		// xml에 지정한 파일명을 매개 변수로 가져온다
		String filename = filterConfig.getInitParameter("filename");
		if(filename == null || filename.equals("")) throw new ServletException("로그 파일의 이름을 찾을 수 없습니다");
		
		try {
			// 가져와서 콘솔로 출력하기
			writer = new PrintWriter(new FileWriter(filename, true), true);
		} catch (IOException e) {
			throw new ServletException("로그 파일을 열 수 없습니다");
		}
	}
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterchain)
			throws IOException, ServletException {
		writer.printf("현재 일시 : %s %n", getCurrentTime());
		String clientAddr = request.getRemoteAddr();
		writer.printf("클라이언트 주소 : %s %n", clientAddr);
		
		filterchain.doFilter(request, response);
		
		String contentType = response.getContentType();
		writer.printf("문서의 콘텐츠 유형 : %s %n", contentType);
		writer.println("-----------------------------");
	}
	private String getCurrentTime() {
		DateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(System.currentTimeMillis());
		return formatter.format(calendar.getTime());
	}
	@Override
	public void destroy() {
		writer.close();
	}
}
  1. web.xml
	<filter>
		<filter-name>Filter03</filter-name>
		<filter-class>ch12.com.filter.LogFileFilter</filter-class>
		<init-param>
			<param-name>filename</param-name>
			<param-value>c://temp//monitor.log</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>Filter03</filter-name>
		<url-pattern>/Ch12/3_filter_process.jsp</url-pattern>
	</filter-mapping>
</web-app>

0개의 댓글