프로그래밍/Servlet&JPS

07 Servlet : Filter

pupu91 2022. 8. 24. 17:03
반응형

 

서블릿 필터

: java.servlet.Filter 인터페이스를 상속 받아 구현하는 클래스

  HTTP 요청과 응답 사이에서 전달 되는 데이터를 가로채어 서비스에 맞게

  변경하고 걸러내는 필터링 작업

 

서블릿 래퍼

: 관련 클래스(ServletRequest, ServletResponse, HttpServletRequest, HttpServletResponse)를 내부에 보관하며

   그 인터페이스들을 구현하고 있는 객체를 참조하여 구현 메소드를 위임

   wrapper class를 상속하면 필요한 메소드만 재정의하여 사용가능

  사용자가 별도의 request나 response 객체를 생성하여 활용할 때 랩퍼 클래스 를 상속하여 활용하면 편하게 원하는 클래    스만 재정의하여 사용 가능

 

web.xml에 Filter 등록

  (1) 필터 등록
  <filter>
  필터 설정이름
  <filter-name>encoding</filter-name> 
  필터를 구현한 클래스
  <filter-class>com.greedy.section02.uses.EncodingFilter</filter-class>
  <init-param> 필터에서 사용할 값 설정
  	초기값 설정 이름
  	<param-name>encoding-type</param-name> 
    설정값
  	<param-value>UTF-8</param-value> 
  </init-param>
  </filter>
  
(2) 필터 매핑
  <filter-mapping>
  	등록된 필터이름 
  	<filter-name>encoding</filter-name>
    요청한 페이지 형식
  	<url-pattern>/*</url-pattern><!-- 모든 요청에 대해서 맵핑 시킨다 -->
  </filter-mapping>
</web-app>

 

 

 

 

 

Fiter Class 설정

: 우클릭 -> NEW -> Filter 

@WebFilter("/first/*")
public class FirstFilter extends HttpFilter implements Filter {
     
    
    public FirstFilter() {
        기본 생성자 -서버 시작시 제일 먼저 호출되고, 그 다음 init 호출됨.
    }
    
    
	public void destroy() {
	    필터 인스턴스가 소멸 될 때 호출 되는 메소드 - 서버 종료시
	}

	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
	
    	필터가 수행될 때 구동하는 메소드로, 요청 객체와 응답 객체를 사용해 일련의 작업을 수행한 뒤
        chain을 통해 가공된 값을 목적지로 전송한다.
		
		
		chain.doFilter(request, response);
        => filter chain : 필터는 chain처럼 서로 연결되어 있는데 연결 되어있는 필터를 순차별로
           doFilter()메소드를 이용하여 실행시키는 인터페이스. 
           마지막 필터가 실행 된 후에는 service() 메소드를 실행시켜 
           서블릿의 메소드(doGet() , doPost())를 실행
           
           dpFilter(request, response) : chain으로 연결되어있는 다음 필터를 실행하는 메소드
		
		서블릿에서 처리 후에 다시 수행할 내용이 있으면 작성한다.
		System.out.println("서블릿 요청 처리 완료!!!");
	}

	

	public void init(FilterConfig fConfig) throws ServletException {
		필터 인스턴스(필터 생성자)가 최초 생성 될 때 호출 되는 메소드
	}

}

 

 

반응형

서블릿 필터 예제

 

1. HTML 작성

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>filter</title>
</head>
<body>

	<h1 align="center">Filter</h1>
	<h3>필터의 라이프 사이클</h3>
	<ul>
		<li><a href="first/filter">Filter 사용하기</a></li>
	</ul>
	
	<hr>
	
	<h3>필터의 활용</h3>
	<form action="member/regist" method="post">
		<label>아이디 : </label>
		<input type="text" name="userId"/>
		<br>
		<label>비밀번호 : </label>
		<input type="password" name="password"/>
		<br>
		<label>이름 : </label>
		<input type="text" name="name"/>
		<br>
		<button type="submit"> 가입하기☆ </button>
	</form>
</body>
</html>

 

 

 

 

 

2.  html에 있는 값을 꺼내오기

@WebServlet("/member/regist")
public class RegistMemberServlet extends HttpServlet {
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		
		/* 값 꺼내기*/
		String userId = request.getParameter("userId");
		String password = request.getParameter("password");
		String name = request.getParameter("name");
		
		System.out.println("userId : " + userId);
		System.out.println("password : " + password);
		System.out.println("name : " + name);
   }

 

 

 

 

3. 인코팅 필터

/*  web.xml에서 필터 등록처리*/
public class EncodingFilter extends HttpFilter implements Filter {
   
   인코딩 타입 필드에 선언
   private String encodingType;
	
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		
        HttpServletRequest에 getMethod() 기능이 있기 때문에 다운캐스팅해야함.(ServletRequest에는 없음)
		
        HttpServletRequest hrequest = (HttpServletRequest) request; 
		if("POST".equals(hrequest.getMethod())) { 
			request.setCharacterEncoding(encodingType);
		}
		
		chain.doFilter(request, response);
	}

	
	public void init(FilterConfig fConfig) throws ServletException {
		/*init 초기화용 메소드*/
		web.xml에서 필터 등록 시 기재한 init-param의 key를 이용하여 fConfig에서 값을 꺼내올 수 있다.
		encodingType = fConfig.getInitParameter("encoding-type");  
	}

}

 

 

 

 

4. 암호화 필터

/* member와 관련 된 서비스일 경우에만 필터를 거치도록 설정하다.*/
@WebFilter("/member/*")
public class PasswordEncryptFilter extends HttpFilter implements Filter {
       
    
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		/*원래의 ServletRequest request를 requestwapper로 바꿔치기 할거임*/
		
		HttpServletRequest hrequest = (HttpServletRequest) request;
		RequestWrapper wrapper = new RequestWrapper(hrequest);
		
		chain.doFilter(wrapper, response);
	}
	
}

 

 

 

 

5. 암호화 로직 작성

HttpServletRequestWrapper에 많은 기능이 있음.
getParameter기능만 오버라이딩해서 사용하기 위해 상속받는 클래스 생성
public class RequestWrapper extends HttpServletRequestWrapper {
	
    부모 클래스에 기본 생성자가 존재하지 않으므로 자식 클래스에서도 request를 부모 클래스로 
    전달해주는 생성자가 필요함.
    public RequestWrapper(HttpServletRequest request) {
		super(request);	
	}
    
    request 객체의 나머지 기능은 원래 기능을 사용하고
    getParameter 메소드만 overriding해서 변경한 메소드를 사용하게 한다
    
    @Override
	public String getParameter(String key) { 
    	
		String value = "";
		
        password라는 키값이 넘어왔을때는 암호화 로직을 수행하고
        password가 아닌 경우 원래기능을 수행시키는 if문 작성
		if("password".equals(key)) {
           
            암호화 로직 작성
		    BCryptPasswordEncoder는 랜덤 솔팅 기법을 적용해서
			input 값이 같더라도 다른 값을 반환하는 것을 확인할 수 있다.
			BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
			value = passwordEncoder.encode(super.getParameter(key)); 
            유저가 입력한 실제 값을 가져와야 되기 때문에 인자에 super.getParameter(key)작성
            
		}else {
			value = super.getParameter(key); //패스워드가 아닌 경우 원래기능(부모)을 수행하겠다
		}
		
		return value;
	}
	
}

    
    
    
}

 

 

암호화 처리 된 패스워드는 동일한 값이 입력 되더라도 매번 실행 시 마다 다른 값을 가지게 된다.
나중에 DB에 이 상태로 기록하게 되면 가입 된 회원 정보로 로그인 할 때 비밀번호가 같은지 어떻게 비교할까?
암호화 된 문자열은 일반 문자열 비교가 불가능하고 matches()라는 메소드를 이용해야한다.

 

BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
System.out.println("비밀번호가 pass01인지 확인 : " + passwordEncoder.matches("pass01", password));
matches의 첫번째 인자는 평문 / 두번째 인자는 인코딩된 결과 

System.out.println("비밀번호가 pass02인지 확인 : " + passwordEncoder.matches("pass02", password));
반응형

'프로그래밍 > Servlet&JPS' 카테고리의 다른 글

09 Servlet / JSP : JSP 특징과 JSP Element 표기법  (0) 2022.08.24
08 Servlet : listener  (0) 2022.08.24
06 Servlet : Session과 Cookie  (0) 2022.08.23
05. Servlet : sendRedirect  (0) 2022.08.23
04. Servlet : forward  (0) 2022.08.23