반응형
서블릿 필터
: 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 |