@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);
log.info("REQUEST [{}][{}][{}]", uuid,requestURI,handler);
if(handler instanceof HandlerMethod){
HandlerMethod hm = (HandlerMethod) handler;
}
return true;
}
@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,handler);
if( ex != null){
log.error("ERROR [{}] [{}]",logId,ex.getMessage());
}
}
}
preHandle : 핸들러 호출 전
uuid를 새로 생성해서 request에 setAttribute 해서 담아둔다.
가 드음 그냥 uuid, requestURI, handler에 관한 정보를 찍는다.
handler instanceof HandlerMethod는
우리가 보통 사용하는 @GetMapping, @PostMapping 등에 포함되어 있는 @RequestMapping이 컨트롤러의 수용방식이라면 handler는 HandlerMethod로 넘어온다.
정적 리소스는 ResourceHttpRequestHandler가 handler로 넘어온다.
저 로그인 컨트롤러에서 사용하는 템플릿은 @GetMapping등을 사용한 컨트롤러이므로 HandlerMethod로 넘어오게 되므로, 제대로 잘 넘어온건지 검사하는 거다.
그 후 그냥 로그를 찍어본다.
그 후 return true를 해 줘야 한다.
그래야 안 멈춘다.
만약 return false로 하면 걸러졌다고 판단하여 false 된다.
postHandler는 많은 정보를 쓰지 않았다.
컨트롤러에서 예외 발생 시 postHandler는 호출되지 않고 통과하기 때문이다. (Exception을 안 받았으니깐)
그래서
응답과 뷰를 거치고 사용자에게 응답메시지를 보내기 직전인
afterCoplecation 에 로그를 남겼다.
저건 인자로 Exception을 받기 때문에, 컨트롤러에서 에러가 나도 호출된다.
여기서 예외에 대한 처리도 가능할 듯 싶다.
이전 preHandle에서 담아뒀던 uuid를 꺼내고 로그에 찍는다.
이렇게 하면 이제 뭐가 사용자 로그인지 추적하기 쉽다.
어차피 이렇게 인터셉터를 거친 후 컨트롤러가 호출 되는 것이라,
아예 그냥 모든 호출에 uuid만 넣어주는 인터셉터를 만드는 것도 나쁘지 않을 듯 싶다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LogInterceptor())
.order(1)
.addPathPatterns("/**")
.excludePathPatterns("/css/**", "/*.ico", "/error");
}
}
@Configuration에 등록해 준다.
WebMvcConfigurer 인터페이스를 상속 받아야
addInterceptors를 구현할 수 있다.
registry에 interceptor를 추가해 주고,
순서를 정해주고,
인터셉터할 경로를 정해주고,
인터셉터에서 제외할 경로들을 지정해 준다.
참고로 여기선 좀 다른게, /*는 자식들만,
/**는 자손들까지다.
.excludePathPatterns("/css/**", "/*.ico", "/error");
이렇게 해 줬으니 이제 저곳의 경로는 인터셉터가 필터링 하지 않는다.
'스프링 > 4. 스프링 MVC-2' 카테고리의 다른 글
60. ArgumentResolver 활용 (0) | 2023.09.09 |
---|---|
59. 스프링 인터셉터 로그인 필터 구현 (0) | 2023.09.09 |
57. 스프링 인터셉터 (0) | 2023.09.09 |
56. 인증 체크 필터 구현 (0) | 2023.09.09 |
55. 필터 구현 (0) | 2023.09.09 |