

- 클라이언트로부터 특정 URL에 대한 접근 요청을 디스패처 서블릿에서 받게 된다. 여기서, 해당 URL이 인터셉터가 적용되도록 등록되어 있다면,
HandlerInterceptor의 PreHandle이라는 메서드로 전달되게 되는데, 이 과정에서 해당 URL에 대한 접근 권한이나 로그인 검증등을 수행한다.- 해당 로직을 처리한 후 이
요청에 맞는 Controller에 전달하게 되고, 컨트롤러에서 로직을 처리한다.그 후 PostHandle 전달되게 된다.postHandle은 컨트롤러 로직이 수행된 후 뷰를 렌더링 하기 전에 수행되는 메서드인데, 응답에 추가 데이터를 넣거나, 요청 처리 후 로깅을 수행한다.- 그 후 클라이언트는 해당 요청에 대한 뷰를 렌더링받게 되고, 응답을 완료받게 된다.
preHandle @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return HandlerInterceptor.super.preHandle(request, response, handler);
}
postHandle@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
`
afterCompletion @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/*.ico", "/error");
registry.addInterceptor(new LoginCheckInterceptor())
.order(2)
.addPathPatterns("/**")
.excludePathPatterns("/", "/members/add", "/login", "/logout","/css/**", "/*.ico", "/error"); }
//...
}
addInterceptor(): 등록할 인터셉터를 추가.addPathPatterns(): 인터셉터를 적용할 URL 패턴을 지정excludePathPatterns(): 인터셉터 적용을 제외할 경로를 지정order() : 여러 개의 인터셉터가 등록되어 있을 때, 각 인터셉터의 우선순위를 지정하는 데 사용. 숫자가 낮을수록 더 높은 우선순위를 갖게 되어 먼저 실행됨. LogInterCeptor
@Slf4j
public class LogInterceptor implements HandlerInterceptor {
public static final String LOG_ID = "logId";
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse
response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
String uuid = UUID.randomUUID().toString();
request.setAttribute(LOG_ID, uuid);
//@RequestMapping: HandlerMethod
//정적 리소스: ResourceHttpRequestHandler if (handler instanceof HandlerMethod) {
HandlerMethod hm = (HandlerMethod) handler; //호출할 컨트롤러 메서드의 모든 정보가 포함되어 있다.
}
log.info("REQUEST [{}][{}][{}]", uuid, requestURI, handler);
return true; //false 진행X }
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse
response, Object handler, ModelAndView modelAndView) throws Exception {
log.info("postHandle [{}]", modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) throws Exception {
String requestURI = request.getRequestURI();
String logId = (String)request.getAttribute(LOG_ID);
log.info("RESPONSE [{}][{}]", logId, requestURI);
if (ex != null) {
log.error("afterCompletion error!!", ex);
}
} }
WebMvcConfigurer
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/*.ico", "/error");
registry.addInterceptor(new LoginCheckInterceptor())
.order(2)
.addPathPatterns("/**")
.excludePathPatterns("/", "/members/add", "/login", "/logout","/css/**", "/*.ico", "/error"); }
//...
}
preHandler
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String requestURI = request.getRequestURI();
log.info("인증 체크 인터셉터 실행 {}", requestURI);
HttpSession session = request.getSession();
if (session == null || session.getAttribute(SessionConst.LOGIN_MEMBER) == null) {
log.info("미인증 사용자 요청");
//로그인으로 redirect
response.sendRedirect("/login?redirectURL=" + requestURI);
return false;
}
return true;
}
}
request.getRequestURI(); 메서드를 통해 사용자가 요청한 URI를 가져온다. request.getSession(); 메서드를 통해 요청 헤더에 세션이 있는지 없는지 검증이 시작된다. session이 null이거나 SessionConst.LOGIN_MEMBER 세션에서 로그인한 사용자 정보를 저장한 키 값을 가져와 null이라면 다시 로그인 페이지로 보낸다. SessionConst.LOGIN_MEMBER은 로그인 성공 시, 이 값에 로그인된 사용자 정보(사용자 ID나 객체 등)이 저장된다. 키로 SessionConst.LOGIN_MEMBER를 전달, 값으로 로그인에 성공한 멤버를 Session에 저장한다. //로그인 성공 처리
//세션이 있으면 있는 세션 반환, 없으면 신규 세션을 생성
HttpSession session = request.getSession();
//세션에 로그인 회원 정보 보관
session.setAttribute(SessionConst.LOGIN_MEMBER, loginMember);
Controller
public String homeLoginV3Spring(
@SessionAttribute(name = SessionConst.LOGIN_MEMBER, required = false) Member loginMember, Model model) {
//세션에 회원 데이터가 없으면 home
if (loginMember == null) {
return "home";
}
//세션이 유지되면 로그인으로 이동
model.addAttribute("member", loginMember);
return "loginHome";
}
@SessionAttributeMember loginMemberModel model