저번에는 사용자가 Servlet이 제공하는 Filter를 사용하여 웹을 관리했다.
지금부터는 Spring이 제공하는 Interceptor에 대해서 알아보고, 적용해보겠다.
Interceptor
- 스프링 인터셉터도 서블릿 필터와 같이 웹과 관련된 공통 관심 사항을 효과적으로 해결할 수 있는 기술이다.
- 서블릿 필터가 서블릿이 제공하는 기술이라면, 스프링 인터셉터는 스프링 MVC가 제공하는 기술이다.
- 둘다 웹과 관련된 공통 관심 사항을 처리하지만, 적용되는 순서와 범위, 그리고 사용방법이 다르다.
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {}
}
- 스프링 인터셉터는 디스패처 서블릿과 컨트롤러 사이에서 컨트롤러 호출 직전에 호출 된다.
- 스프링 인터셉터는 스프링 MVC가 제공하는 기능이기 때문에 결국 디스패처 서블릿 이후에 등장하게 된다. 스프링 MVC의 시작점이 디스패처 서블릿이라고 생각해보면 이해가 될 것이다.
- 스프링 인터셉터에도 URL 패턴을 적용할 수 있는데, 서블릿 URL 패턴과는 다르고, 매우 정밀하게 설정할 수 있다.
- 스프링 인터셉터는 체인으로 구성되는데, 중간에 인터셉터를 자유롭게 추가할 수 있다.
- 서블릿 필터의 경우 단순하게 doFilter() 하나만 제공된다. 인터셉터는 컨트롤러 호출 전( preHandle ), 호출 후( postHandle ), 요청 완료 이후( afterCompletion )와 같이 단계적으로 잘 세분화 되어 있다.
- 서블릿 필터의 경우 단순히 request , response 만 제공했지만, 인터셉터는 어떤 컨트롤러( handler )가 호출되는지 호출 정보도 받을 수 있다. 그리고 어떤 modelAndView 가 반환되는지 응답 정보도 받을 수 있다.
인터셉터는 스프링 MVC 구조에 특화된 필터 기능을 제공한다고 이해하면 된다. 스프링 MVC를 사용하고, 특별히 필터를 꼭 사용해야 하는 상황이 아니라면 인터셉터를 사용하는 것이 더 편리하다.
- Interceptor의 UrlPattern
? 한 문자 일치
* 경로(/) 안에서 0개 이상의 문자 일치
** 경로 끝까지 0개 이상의 경로(/) 일치
{spring} 경로(/)와 일치하고 spring이라는 변수로 캡처
{spring:[a-z]+} matches the regexp [a-z]+ as a path variable named "spring"
{spring:[a-z]+} regexp [a-z]+ 와 일치하고, "spring" 경로 변수로 캡처
{*spring} 경로가 끝날 때 까지 0개 이상의 경로(/)와 일치하고 spring이라는 변수로 캡처
/pages/t?st.html — matches /pages/test.html, /pages/tXst.html but not /pages/
toast.html
/resources/*.png — matches all .png files in the resources directory
/resources/** — matches all files underneath the /resources/ path, including /
resources/image.png and /resources/css/spring.css
/resources/{*path} — matches all files underneath the /resources/ path and
captures their relative path in a variable named "path"; /resources/image.png
will match with "path" → "/image.png", and /resources/css/spring.css will match
with "path" → "/css/spring.css"
/resources/{filename:\\w+}.dat will match /resources/spring.dat and assign the
value "spring" to the filename variable
1.SessionInterceptor.java를 생성한다.
경로 : (\src\main\java\com\project\web\session\SessionInterceptor.java)
package com.project.web.session;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;
public class SessionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//요청이 들어온 URI
String requestURI = request.getRequestURI();
//사용자 정보가 저장된 Session
HttpSession session = request.getSession();
//세션이 없거나, 세션에 로그인정보가 없다면
if (session == null || session.getAttribute(SessionConst.SESSION_NAME) == null) {
response.sendRedirect("/sign/signIn?redirectURL=" + requestURI);
return false; //return타입이 boolean이기때문에 false를 해줘야 다음 process로 넘어가지 않는다.
}
return true;
}
}
2.@Configuration 클래스에서 WebMvcConfigurer를 implements하여, addInterceptors메소드를 Override한다.
경로(\src\main\java\com\project\config\WebConfig.java)
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SessionInterceptor())
.order(0) //interceptor의 순서를 정한다.
.addPathPatterns("/**") // [/**]는 전부 Interceptor의 범위에 있다는 뜻이다.
.excludePathPatterns("/", "/sign/*", "/assets/*", "/images/*"); //다음과 같은 url은 interceptor에서 제외한다.
}
3.서버 재시작후 테스트
로그인하지 않은 상태에서 localhost:9090/generic으로 접근한다.
로그인 페이지로 redirect됐으며, 접근 시도했던 /generic경로를 redirectURL파라미터로 던진다.
4.로그인
성공!
다음에는
- ArgumentResolver를 사용하여 Session상태를 좀 더 쉽게 확인하는 기능.
- 로그인 여부에 따라 홈 화면을 구분.
- 로그아웃기능.
을 만들 예정이다.
'프로젝트[종료]' 카테고리의 다른 글
17. Spring Boot 오류 처리하기 (0) | 2023.06.01 |
---|---|
16. ArgumentResolver사용하기, 로그아웃 기능 추가 (0) | 2023.05.11 |
14. Servlet Filter 적용하기 (0) | 2023.05.04 |
13. 로그인 사용자 Session 처리하기 (0) | 2023.04.28 |
12.회원가입 기능 만들기(2) (2) | 2023.04.27 |