티스토리 뷰

728x90
반응형

그동안 jsp파일들에 한글 인코딩 설정을 계속해서 해왔다. 

반복되는 작업이 번거로우므로, Filter을 사용하여 인코딩 설정을 해줄 수 있다.

 

 

위 그림에서처럼 클라이언트가 요청을 보내면, 해당 요청을 서버가 작업하기 전에 Filter가 작업을 가로채, Filter 안에서 인코딩 등의 필요한 작업을 수행할 수 있다.

이렇게 하면, 다른 jsp 파일들은 Filter 안의 작업을 신경쓰지 않아도 된다.

인코딩 뿐 아니라 로그인 등, 필요한 기능들에 Filter를 사용할 수 있다.


[ 요청을 가로채서 중간에 원하는 작업을 할 수 있는 필터 만들기 ]

1. javax.servlet.Filter 인터페이스 구현하기

2. web.xml을 만들고, 필터를 정의하고 맵핑하기(web.xml 대신 어노테이션 사용 가능)

3. doFilter() 메소드 안에서 원하는 작업 수행하기

 

 

필터에는 3가지 메소드가 있다.

1) destroy() : 필터 객체가 제거될 때 실행됨

 

2) doFilter() : 필터의 핵심 메소드로, 클라이언트가 요청할 때마다 실행됨

- HttpServletRequest 객체와 HttpServletResponse 객체가 doFilter의 인자로 전달뙤는데, 부모 타입인 ServleetRequest, ServletResponse에 담겨 전달된다.

- 따라서 두 객체를 HttpServletResponse, HttpsServletRequest 타입으로 사용하고 싶을 때는 캐스팅을 해주어야 한다.

 

3) init(): 필터가 최초 사용될 때 한 번만 호출됨


예제를 통해 살펴보자.

 

예제 1 - EncodingFilter 구현하기

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
  <display-name>Step05_Filter</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <!-- EncodingFilter 정의하기 -->
  <filter>
  	<filter-name>EncodingFilter</filter-name>
  	<filter-class>test.filter.EncodingFilter</filter-class>
  <init-param>
  	<param-name>encoding</param-name>
  	<param-value>utf-8</param-value>
  </init-param>
  </filter>
  <!-- EncodingFilter 맵핑하기(어떤 pattern의 요청이 왔을 때 동작하게 할 것인지 -->
  <filter-mapping>
  	<filter-name>EncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern><!-- context하위의 모든 요청에 대해 수행-->
  </filter-mapping>
</web-app>

 

톰캣 서버가 start 되는 시점에 web.xml을 읽어 동작을 준비한다.

따라서, web.xml에 필터를 정의해야 한다.

여기서는 필터가 context 하위 모든 요청에 대해 수행되도록 설정했다.


EncodingFilter.java

package test.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 EncodingFilter implements Filter {
	//초기화 파라미터를 읽어와서 저장할 필드 
	private String encoding;
	@Override
    //필터 객체가 제거될 때 실행되는 메소드
	public void destroy() {

		
	}
	//클라이언트의 요청이 있을 때마다 실행. 필터 핵심 메소드
	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		System.out.println("EncodingFilter doFilter() 동작중...");
		//1. 만일 요청 인코딩이 설정되지 않았다면
		if(request.getCharacterEncoding()==null) {
			//인코딩 설정하기
			request.setCharacterEncoding(encoding);
			//request.setCharacterEncoding("utf-8");
			
		}
		
		//2.요청의 흐름 계속 이어가기
		chain.doFilter(request, response);
		
	}
	//필터가 최초 사용될 때 한 번만 호출되는 메소드
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		//web.xml에 encoding 이라는 키값으로 저장된 utf-8 문자열 얻어오기
		encoding = filterConfig.getInitParameter("encoding");
	}
	
	

}

 

chain.doFilter은 요청의 흐름을 계속 이어가도록 해준다. 

doFilter() 안에서 request.setCharacterEncoding("utf-8")로 바로 인코딩 설정을 할 수도 있지만, init()으로 web.xml에 저장된 "utf-8"이라는 문자열을 얻어와 문자열을 활용할 수도 있다.


예제 2 - LoginFilter 구현하기

"web.xml 필터 설정을 대신하여 어노테이션으로 동작시키기"

 

LoginFilter.java

package test.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;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

//web.xml 필터 설정을 대신해서 어노테이션으로 동작하게 할수 있다.
@WebFilter("/private/*")
public class LoginFilter implements Filter{

   @Override
   public void destroy() {
      // TODO Auto-generated method stub
      
   }

   @Override
   public void doFilter(ServletRequest request, ServletResponse response, 
         FilterChain chain)
         throws IOException, ServletException {
      //1. 로그인된 클라이언트인지 확인( HttpSession 이 필요 => HttpServletRequest 가 필요)
      HttpServletRequest req=(HttpServletRequest)request;
      HttpSession session=req.getSession();
      String id=(String)session.getAttribute("id");
      
      //2. 만일 로그인된 상태라면 관여하지 않고 요청의 흐름을 이어가면 되고
      if(id != null) {
         chain.doFilter(request, response);
      }else {
         //3. 로그인된 상태가 아니라면 로그인 폼으로 리다일렉트 이동시킨다. ( HttpServletResponse 필요)
         HttpServletResponse res=(HttpServletResponse)response;
         String cPath=req.getContextPath();
         res.sendRedirect(cPath+"/test/loginform.jsp");
      }
   }

   @Override
   public void init(FilterConfig filterConfig) throws ServletException {
      // TODO Auto-generated method stub
      
   }

}

어노테이션 부분에서 private의 모든 하위 경로에서 필터가 수행될 수 있도록 설정했다.

위의 주석을 잘 읽어보고 매커니즘을 이해하면 좋을 것이다.


파일 구조


로그인 필터와 인코딩 필터가 잘 적용되었는지 확인해보자.

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/index.jsp</title>
</head>
<body>
	<h1>인덱스 페이지 입니다.</h1>

	<ul>
		<li><a href="private/play.jsp">놀러가기(로그인 필요)</a></li>
		<li><a href="private/study.jsp">공부하러 가기(로그인 필요)</a></li>
	</ul>

	
</body>
</html>

private 폴더 안의 play.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
    //로그인된 아이디 읽어오기
    String id = (String)session.getAttribute("id");
    //만일 로그인을 하지 않았다면
    /* if(id==null){
    	//로그인 페이지로 리다이렉트 이동
    	String cPath = request.getContextPath();
    	response.sendRedirect(cPath+"/test/loginform.jsp");
    } */
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>/private/play.jsp</title>

</head>
<body>
<p>
	<strong><%=id %></strong>님 신나게 놀아보아요
</p>
<a href="../index.jsp">인덱스로 가기</a>
</body>
</html>

 

private의 하위 파일들에 LoginFilter가 적용되도록 했으므로, '놀러가기' 클릭 시, 로그인 폼이 나오는 것을 확인할 수 있다.

또한, 인코딩 필터는 context 하위 모든 파일에 적용되도록 했으므로, 인코딩 설정을 하지 않아도 한글 인식에 문제가 없다.

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함