728x90
문제 시나리오
- 사용자의 네트워크 지연
- 사용자의 잘못된 조작
중복요청이 발생 할 경우 데이터의 동시성 문제로 일관된 데이터가 입력이 될 수 있기 때문에 중복요청을 방지 하고자 했다.
많은 방법이 있지만 Spring AOP (Aspect-Oriented Programming)를 활용하여 문제를 해결하고자 했다.
@Aspect
@Component
public class DuplicateRequestAspect
{
private Set<String> requestSet = Collections.synchronizedSet(new HashSet<>());
@Pointcut("within(*..*Controller)")
public void onRequest() {}
@Around("onRequest()")
public Object duplicateRequestCheck(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String httpMethod = request.getMethod();
// GET 메소드인 경우 중복 체크를 하지 않음
if ("GET".equalsIgnoreCase(httpMethod)) {
return joinPoint.proceed();
}
String requestId = joinPoint.getSignature().toLongString();
if (requestSet.contains(requestId)) {
// 중복 요청인 경우
return handleDuplicateRequest();
}
requestSet.add(requestId);
try {
// 핵심 로직 실행
return joinPoint.proceed();
} finally {
// 실행 완료 후 삭제
requestSet.remove(requestId);
}
}
private ResponseEntity<Object> handleDuplicateRequest() {
// 중복 요청에 대한 응답 처리
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("중복된 요청 입니다");
}
}
AOP는 컨트롤러가 요청을 받을 때 해당 요청을 받으면 requestSet 에 넣고 요청이 완료되면 없애준다.
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String httpMethod = request.getMethod();
// GET 메소드인 경우 중복 체크를 하지 않음
if ("GET".equalsIgnoreCase(httpMethod)) {
return joinPoint.proceed();
}
HttpServletRequest를 사용하여 Get 메소드의 경우 중복체크를 하지 않도록 설정하였다.
Get은 빈번하게 일어나기 때문에 제외 시켜 주었다.
String requestId = joinPoint.getSignature().toLongString();
if (requestSet.contains(requestId)) {
// 중복 요청인 경우
return handleDuplicateRequest();
}
requestSet.add(requestId);
try {
// 핵심 로직 실행
return joinPoint.proceed();
} finally {
// 실행 완료 후 삭제
requestSet.remove(requestId);
}
}
해당 요청의 정보를 변수에 담아 해당 정보가 requestSet에 존재 여부를 확인 후
존재 하지 않으면 requestSet에 담아주고 로직을 실행시킨 후 실행 완료 후 Set에서 삭제 해준다.
존재하면
private ResponseEntity<Object> handleDuplicateRequest() {
// 중복 요청에 대한 응답 처리
return ResponseEntity.status(HttpStatus.TOO_MANY_REQUESTS).body("중복된 요청 입니다");
}
중복된 요청이라는 메세지를 호출해 준다.
728x90
'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
[Spring] 선착순 이벤트 구현 ( 동시성 Pessimistic Lock) (3) | 2024.01.04 |
---|---|
[Spring] @Constraint로 커스텀 Vaildatation 만들기 (0) | 2023.12.27 |
[JAVA] Stream 이해 (Parallelism 병렬처리) (0) | 2023.06.12 |
[JAVA] Stream 이해 (Lazy 지연연산) (0) | 2023.06.12 |
[JAVA] TDD / Testcode (mockito) (0) | 2023.05.07 |