티스토리 뷰
현상
서버에서 rest api 사용 history를 트래킹 하기 위해 아래와 같이 사용하고 있었다.
@Component
public class HttpInterceptor implements AsyncHandlerInterceptor {
final Logger L = LoggerFactory.getLogger(this.getClass());
@Autowired
RestHistoryService restHistoryService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (!"OPTIONS".equals(request.getMethod()) && URL.contains(Const.REST_URL)) {
// 여기서 rest 관련 정보 history create
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
if (response.getStatus() != 200) {
// 여기서 실패 history update
}
}
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
}
}
그리고 WebMvcConfigurer에서 interceptor 를 추가함 (여기서 rest 패턴만 따로 빼도 됨)
@Configuration
public class InterceptorConfiguration implements WebMvcConfigurer {
@Autowired
HttpInterceptor httpInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(httpInterceptor).addPathPatterns("/**/**");
}
}
잘 사용하고 있었는데 이슈가..
RestHistory가 두개씩 쌓이는 현상이 발생했다. (사내 데이터라 캡쳐못함)
처음엔 연속적으로 요청이 온다고 생각했는데 Debugging 해보니까 preHandle을 두번 타는걸 확인.
원인은?
DeferredResult 로 응답을 주는 API가 추가 됐었는데, AsyncHandlerInterceptor는 Async로 동작했을 때 Interceptor의 flow가 다르다. (Callable같은 Async Response 다 포함)
※ 참고 : www.logicbig.com/tutorials/spring-framework/spring-web-mvc/async-intercept.html
Spring MVC - Intercepting Async Requests using AsyncHandlerInterceptor
Spring MVC - Intercepting Async Requests using AsyncHandlerInterceptor [Last Updated: Feb 13, 2018]
www.logicbig.com
위 링크를 참고해보면 interceptor가 아래와 같은 흐름으로 동작한다.
preHandle -> afterConcurrentHandlingStarted -> preHandle -> postHandle -> afterCompletion
기존에 preHandle 들어올 때마다 history를 저장하고 있으니 Async 처리될 때는 두번씩 찍힌거다.
해결은
위 링크에서는 Async의 흐름이 다르니 아래와 같이 구분하라는 뜻이었다.
| Within interceptor, to distinguish between the initial request and the subsequent dispatch after asynchronous handling completes, interceptors can check whether the javax.servlet.DispatcherType returns from ServletRequest#getDispatcherType() call is "REQUEST" or "ASYNC". |
이력은 어떤 요청이 왔는지 체크하기 위해서니까 아래와 같이 preHandle에서 REQUEST 타입일 때만 남기기로 함
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
if (DispatcherType.REQUEST.equals(request.getDispatcherType())) {
// REQUEST 타입 일때만 이력 남김
}
return true;
}'Programming & Solution > Java' 카테고리의 다른 글
| [Junit] 템플릿 (0) | 2021.03.10 |
|---|---|
| [SpringBoot] https / http2 적용 (0) | 2020.04.21 |
| [SpringBoot] CP Connection 이슈 트러블슈팅 (0) | 2020.03.10 |
| [SpringSecurity] URL 더블슬래시 허용 (2) | 2019.08.28 |
| [SpringBoot] OAUTH2 설정 (2) | 2019.08.22 |
- Total
- Today
- Yesterday
- 사토시 나가모토
- Bruteforce
- 블록체인
- CARDANO
- 스프링
- Nealford
- Vue.js
- 아키텍처
- 동적계획법
- Redis
- architecture
- 알고리즘
- 백준
- DP
- white paper
- Bitcoin
- 비트코인
- kubernetes
- gRPC
- excel parsing
- Spring
- leetcode
- 카르다노
- vuejs
- Blockchain
- 암호화폐
- Java
- 스프링 시큐리티
- SpringBoot
- k8s
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 |