Programming/Spring Boot
[SpringBoot] 스크롤 API (Offset vs Keyset-Filtering)
실무에서는 대량의 데이터를 조회한 뒤 수정하는 일이 종종 발생합니다. 예를 들어, 브랜드명이 매일우유에서 매일유업으로 바뀐다면 판매상품 내 brandName 필드값이 매일우유인 엔티티를 모두 찾아 브랜드명을 매일유업으로 바꿔주어야 합니다. 이때 변경해야할 엔티티가 수만건이라면 페이징 처리를 안할 시 Out-of-Memory가 발생할 수 있습니다. 따라서, 우리가 흔히 부르는 스크롤 방식으로 100건씩 끊어서 조회한 뒤 update를 하는 방법을 취하게 됩니다. SpringBoot 3.1 버전부터는 스크롤 API를 공식적으로 지원합니다. Spring Data JPA 3.1 버전을 추가함으로써 우리는 스크롤 방식의 페이징 처리를 간단하게 구현할 수 있습니다. 이번 글에서는 Offset 방식과 Keyset-F..
[SpringBoot] Logback 파일과 Docker 볼륨 연동하기
스프링부트 서버를 띄울 때 로컬에선 콘솔로 에러 로그를 확인하면 되지만, 원격 EC2에 서버를 띄우면 에러 로그 확인이 어려워집니다. 장애 대응 시 에러 로그를 바로 확인하는 것이 중요하기에, 이번 글에서는 에러 로그를 어떻게 하면 바로 확인할 수 있는지 알아보고자 합니다. 모든 설명은 EC2에 도커 컨테이너 기반으로 서버를 띄우고, 로깅 프레임워크로 Logback을 사용한다는 가정하에 진행하겠습니다. Logback 적용 전 아직 Logback을 적용하지 않았다면 스프링부트 서버의 로그는 파일 형태가 아닌 표준 출력을 따를 것입니다. 따라서 docker logs 명령어를 통해 로그를 확인할 수 있습니다. docker logs 명령어는 컨테이너 내부에서 출력을 보여주는 명령어입니다. docker logs ..
Circular view path [error] 원인과 해결방법
상황 운영 서버의 그라파나를 확인해보니 API 500 에러와 함께 아래 로그가 발생하고 있었다. javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup! 문제 원인 구글링을 해보니 에러가 발생한 원인은 크게 2가지로 나뉜다. @Controller 사용 시 @GetMapping으로 매핑된 url과 view의 이름이 같은 경우 클라이언트에서 잘못된 url을 요청했을 때 에러를 핸들링할 ErrorController를 만들어주지 않았을 경우 나같은 경우 2번에 해당했다. Nginx log를 보니 ..
Lombok 정리
@Getter와 @Setter, @RequiredArgsConstructor와 같이 기본적으로 사용하는 애노테이션에 대한 설명은 생략한다. @FieldDefaults Adds modifiers to each field in the type with this annotation. Complete documentation is found at the project lombok features page for @FieldDefaults. If makeFinal is true, then each (instance) field that is not annotated with @NonFinal will have the final modifier added. If level is set, then each (inst..
CORS 설정시 PUT, DELETE 요청하면 OPTIONS 403에러가 나는 경우
백엔드 API 구현한 뒤 다음과 같이 CORS 전역 설정을 하였는데 오류가 났었습니다. 게시글 조회, 등록의 경우 CORS 설정이 잘 되었으나 게시글 수정, 삭제할 때 CORS 설정이 적용이 안되서 OPTIONS 403 에러가 났었습니다. @Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*"); } } 해결 방법 오버라이딩한 메소드 addCorsMappings의 인자값 CorsRegistry를 보면 다음 메소드를 볼 수 있습니다. 그래서 Ma..