Servlet Filter

최주영·2023년 5월 23일
0

Servlet

목록 보기
4/9

✅ Filter

  • 서블릿으로 연결하기전에 필터를 사용해서 특정 문지기역할을 하는것
  • 공통으로 처리할 로직을 처리할때 사용
    EX) 인증확인, 권한확인, Log출력, Encoding처리
    -> 필터는 한개뿐 아니라 다수개도 놓을 수 있음 (순서대로 실행됨)


✅ 필터 구현하기

    1. 일반클래스를 생성하고 Filter인터페이스를 구현한다.
    1. 생성한 클래스를 filter로 등록
      1) web.xml 방식
      2) 어노테이션 방식
	<!--  1) web.xml 방식 -->
	<!-- 필터등록하기 -->
	<filter>
		<filter-name>basicfilter</filter-name>
		<filter-class>com.filtertest.common.filter.BasicFilter</filter-class>
	</filter>
	
	<filter-mapping>
		<filter-name>basicfilter</filter-name>
		<url-pattern>/*</url-pattern>
		<!-- /* 는 전체경로임 -->
		<!-- /basicfilter.do 로 하면 요청할때만 필터처리됨-->	
	</filter-mapping>
//filter 주소와 매핑된 클래스
package com.filtertest.common.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;
import javax.servlet.http.HttpServletRequest;

public class BasicFilter implements Filter{ // Filter 인터페이스 구현해야함

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException { // 추상메소드 doFilter 구현
		
		System.out.println("BasicFilter 실행함!");
	
		// wrapper클래스 적용하기
		MyRequestWrapper mrw 
		= new MyRequestWrapper((HttpServletRequest)request);
		
        //FilterChain : 다른필터 또는 연결된 서블릿을 가지고 있는 객체, 
		//			  다음 필터또는 서블릿 호출할 때 사용 (doFilter()메소드 호출)
		// 다음 로직이 실행될 수 있게 하기
		// chain.doFilter() 이 없으면 응답을 하지 않고 끝내버린 것임
		chain.doFilter(mrw, response);
	}
}

어노테이션 방식

  • 프로젝트 우클릭 -> Filter 만들기 -> 클래스이름은 마음대로 짓기
  • Servlet 방식과 URL pattern중에 선택 !
  • 밑에 예시 패턴은 해석하면 -> admin으로 시작하는 모든 주소는 이 필터 거처가야한다는 뜻
// 위 어노테이션방식으로 만든 후
// 관리자만 접속할 수 있도록 로직 만듬
package com.filtertest.common.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.HttpFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


//@WebFilter("/admin/*")
public class AdminCheckFilter extends HttpFilter implements Filter {
       

    public AdminCheckFilter() {
        super();
        // TODO Auto-generated constructor stub
    }


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

// ServletRequest 의 자식클래스 -> HttpServletRequest
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpSession session = ((HttpServletRequest)request).getSession(); // HttpServletRequest로 형변환해줘야함
		String loginId = (String)session.getAttribute("loginId");
		System.out.println(loginId);
		if(loginId!=null && loginId.equals("admin")) {
			chain.doFilter(request, response); // 위 조건이맞으면 응답을함
		}else {
			((HttpServletResponse)response) // response도 HttpServletRequest로 형변환해야 사용가능
			.sendRedirect("/03_filter_listener/");
		}
	}


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

}

✅ 모든 페이지에 필터를 통해 인코딩 설정

  • 패턴을 "/*"로 지정함으로써 모든 경로에 필터가 거치도록 함
  • 더 이상 서블릿에서 인코딩 설정할 필요 없음
  • 이와 같이 공통적으로 실행할 로직에 대해서 처리할 때 filter 사용
package com.filtertest.common.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.HttpFilter;


@WebFilter("/*")
public class EncodingFilter extends HttpFilter implements Filter {
       
    public EncodingFilter() {
     
    }

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

	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");
		
		chain.doFilter(request, response);
	}

	public void init(FilterConfig fConfig) throws ServletException {
		
	}

}

✅ wrapper 클래스 적용

// MyRequestWrapper 클래스
package com.filtertest.common.filter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class MyRequestWrapper extends HttpServletRequestWrapper{
	
	public MyRequestWrapper(HttpServletRequest request) { 
		// HttpServletRequestWrapper 상속받으려면
		// 매개변수있는 생성자가 반드시 있어야함
		super(request);
	}

// atl + shift + s + v  ->
	@Override
	// 해당 클래스의 getParameter 클래스의 메소드를 재정의함
	public String getParameter(String name) {
		
		String oriData = super.getParameter("data"); // 원본데이터
		return oriData+"-bs-";
	}
	
}


// EncodingFilterTestServlet 클래스
package com.filtertest.controller;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.filtertest.common.filter.MyRequestWrapper;


@WebServlet("/data.to")
public class EncodingFilterTestServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       

    public EncodingFilterTestServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			
		MyRequestWrapper mrw = new MyRequestWrapper(request); // MyRequestWrapper 객체 생성
		String data = request.getParameter("data"); // 원본
		String mydata = mrw.getParameter("data"); // bs마지막에 추가됨
        // 위 getParmeter은 기존 request의 getParmeter이 아닌, 새로 재정의한 getParameter로 들어간다
		System.out.println(data);
		System.out.println(mydata);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글