2020. 7. 8. 21:49ㆍ🔴 Spring
사용목적 = 공통적으로 처리할 업무 진행
권한 체크, 로그인 관리, 페이지 인코딩 등의 업무를 공통적으로 여러 곳에서 처리해야 하는 상황이라면,
같은 코드를 중복해서 사용하기보다는 공통 프로세스로 떼어내어 따로 개발하는 게 더 효율적이다.
filter와 interceptor 모두 '공통'적으로 어떠한 로직을 수행하는것인데,
실행 흐름을 보면 (1) filter - (2) interceptor 이렇게 있다.
따라서 요청이 들어오면 가장 먼저 거치는 부분은 filter, 그다음엔 interceptor이다.
Filter
- 요청&응답 거른 뒤 정제하는 역할
- 스프링 콘텍스트 외부에 존재 -> 스트링과 무관한 자원에 대해 동작함
- 앞단에서 요청 내용을 변경하거나 체크할 수 있음
- 자원처리가 끝난 후, 응답 내용을 변경할 수 있음
- web.xml에 등록
- init(), doFilter(), destroy()
- 사용 예시 ) 인코딩 변환, XSS방어
예시 1 (로그인 체크) :
<web.xml>
<!-- web.xml에서 매핑하든가 클래스 내부에서 annotation으로 적용하든가 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<LoginCheckFilter.java>
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.RequestDispatcher;
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;
@WebFilter({ "/LoginCheckFilter", "/mypage/*" })
public class LoginCheckFilter implements Filter {
public LoginCheckFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
//로그인 정보 -> session에 저장되어있음
//Parameters:create - true to create a new session for this request if necessary; false to return null if there's no current session
//Returns:the HttpSession associated with this request or null if create is false and the request has no valid session
HttpSession session = req.getSession(false);
boolean loginchk = false;
// 1. 로그인 되어있는지 확인 -> 되어있으면 true
if(session != null && session.getAttribute("LoginInfo") != null) {
loginchk = true;
}
// 2. 로그인 되어있는지에 따라 다른 처리
if(loginchk) {
// 로그인 OOO -> chain => 등록한 다른 필터에 변경된 요청사항들을 보냄
chain.doFilter(request, response);
} else {
// 로그인 XXX -> redirect
resp.sendRedirect(req.getContextPath()+"/session/member/loginForm.jsp");
// RequestDispatcher dispatcher = request.getRequestDispatcher("/session/member/loginForm.jsp");
// dispatcher.forward(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
예시 2 (인코딩) :
<CharactorEncodingFilter.java>
package 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.annotation.WebInitParam;
// 이부분 주석처리하면 실행 안됨
//@WebFilter(
// urlPatterns = { "/*" },
// initParams = {
// @WebInitParam(name = "encoding", value = "UTF-8")
// })
public class CharacterEncodingFilter implements Filter {
private String encoding;
public CharacterEncodingFilter() {
// TODO Auto-generated constructor stub
}
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// encoding 적용하기
request.setCharacterEncoding(encoding);
// 다른 필터에 체인처럼 연결
chain.doFilter(request, response);
}
public void init(FilterConfig fConfig) throws ServletException {
encoding = fConfig.getInitParameter("encoding");
if (encoding == null) {
encoding = "UTF-8";
}
}
}
Interceptor
- 컨트롤러에 들어오는 요청(HttpRequest)과 응답(HttpResponse)을 가로채는 역할
- DispatcherServlet이 컨트롤을 호출하기 전/후에 끼어듦 -> 스프링 콘텍스트 내부에서 컨트롤러에 관한 요청, 응답 처리함
- 모든 bean 객체에 접근 가능
- 여러 개 사용 가능
- preHandler(), postHandler(), afterCompletion()
- 사용 예시 ) 로그인 체크, 권한 체크, 로그 확인
Filter & Interceptor 차이점
1. 호출 시점
Filter는 DispatcherServlet이 실행되기 전 , Interceptor는 DispatcherServlet이 실행된 후
2. 설정 위치
Filter는 web.xml , Interceptor는 spring-servlet.xml
3. 구현 방식
Filter는 web.xml에서 설정을 하면 구현이 가능하지만, Interceptor는 설정은 물론 메서드 구현이 필요하다.
참고:
'🔴 Spring' 카테고리의 다른 글
spring security 사용하여 암호화하기 (0) | 2021.07.09 |
---|---|
스프링을 이용하여 메일발송해보자 (gmail기반) (1) | 2020.07.08 |
RESTful(9) - @RequestEntity, RestTemplate 사용하기 (0) | 2020.05.12 |
RESTful(8) - @RequestBody & @ResponseBody란? (0) | 2019.11.26 |
RESTful(7) - RESTful server구현해보기 (간단예제!) (0) | 2019.11.26 |