Dev/JSP & Servlet

필터구현 (로그인 검사, 캐릭터 인코딩, 시간 측정)

창문닦이 2019. 3. 6. 00:51

필터

필터란 웹 어플리케이션에서 사용하는 서블릿이나 JSP에 도착하기 전에 Request의 내용을 조작한 후 서블릿이나 JSP에 전송하는 기능. (즉, 클라이언트와 서버 사이에 필터가 존재하고, 클라이언트->서버로 가는 request와 서버->클라이언트로 넘어가는 response 가 필터를 거침에 따라 데이터가 가공되는 것) 주로 보안을 위해 사용하고 요청정보의 인코딩작업 등에 사용된다.


참조 사이트 https://programmingsummaries.tistory.com/82


세션 시간 측정 필터

특정 페이지가 실행이 될 때, 페이지가 조회되는 시간을 필터를 통해 조회하고자 함

TimerFilter.java

package com.filter;

import java.io.IOException;

import javax.servlet.Filter;


public class TimerFilter implements Filter{

private FilterConfig config;

@Override

public void destroy() {

//3. 필터에서 나갈때 실행

}

@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

//2. 필터작업

long before = System.currentTimeMillis(); //시작시간

chain.doFilter(request, response);

long after = System.currentTimeMillis(); //종료시간

String uri;

if(request instanceof HttpServletRequest){

필터가 감싸고 있기 때문에 클라이언트가 보낸 request가 맞는지 확인 후 다운캐스팅 작업이 필요함

//downcast

HttpServletRequest req = (HttpServletRequest)request;

uri = req.getRequestURI();

//config.getServletContext().log(uri+":"+(after-before)+"ms");//로그 만드는 방법

System.out.println(uri+":"+(after-before)+"ms");

}

}

@Override

public void init(FilterConfig config) throws ServletException {

//1. 필터에 들어올때 처음실행

this.config = config;

}

}

콘솔 실행 화면


어떠한 페이지든 모두 체크하도록 * 설정

<!-- Servlet 타이머필터 -->

<filter>

<filter-name>timerFilter</filter-name>

<filter-class>com.filter.TimerFilter</filter-class>

</filter>

 <filter-mapping>

<filter-name>timerFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>




한글 인코딩 필터

public class CharsetEncodingFilter implements Filter{

private String charset;

@Override

public void destroy() {

}

@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

String uri;

if(request instanceof HttpServletRequest){

//downcast

HttpServletRequest req = (HttpServletRequest)request;

uri = req.getRequestURI();

if(req.getMethod().equalsIgnoreCase("POST")){

if(uri.indexOf("ajax.do")!=-1){

//ajax.do 페이지를 요청할 경우 인코딩 방식을 euc-kr로 설정

req.setCharacterEncoding("euc-kr");

}else{

req.setCharacterEncoding("UTF-8");

}

}

//다른필터가 있다면 그 필터를 찾아감. 현재(필터3개존재)는 (다른 필터들을 다 거친 후)서버 찾아감

chain.doFilter(request, response);

}

}

@Override

public void init(FilterConfig config) throws ServletException {

charset = config.getInitParameter("charset");

}

}


실행 화면


어떠한 페이지든 모두 체크하도록 * 설정

<!-- CharsetEncodingFilter -->

<filter>

<filter-name>charsetFilter</filter-name>

<filter-class>com.filter.CharsetEncodingFilter</filter-class>

<init-param>

<param-name>charset</param-name>

<param-value>UTF-8</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>charsetFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>




로그인 검사 필터

특정페이지로 접근할때(/bbs/*) 무조건 로그인 페이지가 먼저 처리될 수 있도록 필터를 추가한 것

사용자가 어떠한 주소로 접근을 하는지에 상관없이, 가는 곳은 하나로 설정이 가능하다.

public class LoginFilter implements Filter{

@Override

public void destroy() {

}

@Override

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

boolean flag = false;

if(request instanceof HttpServletRequest){

HttpServletRequest req = (HttpServletRequest)request;

//세션 받아옴

HttpSession session = req.getSession();

if(session!=null){

//CustomInfo info = (CustomInfo)session.getAttribute("customInfo");

//세션에 여러 데이터를 담을 수 있지만 공간이 좁기 때문에 클래스로 만들어 하나만 보냄.

if(session.getAttribute("customInfo")!=null){

flag = true;

}

}

if(flag){

//로그인을 했을경우 true

chain.doFilter(request, response);

}else{

//로그인 하지 않았으므로 로그인페이지로 포워드

RequestDispatcher rd = request.getRequestDispatcher("/member/login.jsp");

rd.forward(request, response);

}

}

}

@Override

public void init(FilterConfig config) throws ServletException {

}

}


<!-- 로그인 필터 -->

<filter>

<filter-name>loginFilter</filter-name>

<filter-class>com.filter.LoginFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>loginFilter</filter-name>

<url-pattern>/bbs/*</url-pattern>

</filter-mapping>

<filter>

<filter-name>loginFilter1</filter-name>

<filter-class>com.filter.LoginFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>loginFilter1</filter-name>

<url-pattern>/board/*</url-pattern>

</filter-mapping>


( web.xml에 설정해놓은 bbs, board에 있는 페이지라면) 접근 주소에 상관없이 로그인 화면으로 연동되는 것을 확인할 수 있다.




필터 체인

지금까지 3가지 필터를 구현해보았다. 여러 개의 필터가 모여 하나의 필터 체인을 구성할 수 있다클라이언트의 Request가 서버에 전달되는 과정에서 필터 3개를 거쳐서 서버에 전달되고, 서버에서 응답하는 Response 도 필터 3개를 거쳐서 클라이언트에게 전달된다는 개념을 이해하자.