본문 바로가기
  • 개발하는 곰돌이

spring boot39

[토이프로젝트] KBO 경기 일정 수집하기(2) - Upsert를 통한 중복 데이터 처리 목차/pages/KBO-경기-일정-수집하기-시리즈Upsert의 필요성1편에서 경기 정보를 수집하고 DB에 저장했지만 경기 정보는 매일매일 바뀌게됩니다. 시즌 초에 전체 일정이 나오지만 매일 경기를 진행하면서 경기 정보는 수시로 바뀝니다. 게다가 날씨에 따라 취소 경기가 발생하여 더블헤더 경기가 편성되거나 추후 잔여경기 일정으로 편성될 수도 있죠. 따라서 수집된 경기 목록 중에서 DB에 저장된 경기는 업데이트하고 새로운 경기만 저장하는 Upsert 전략이 필요합니다.Upsert 전략을 구성하자!우선 어떻게 Upsert 전략을 구성할지 생각해봤습니다. KBO 웹사이트에서 경기 정보를 수집하여 파싱하면 경기 정보 엔티티 객체가 모인 리스트가 생성됩니다. 이 경기 정보 객체들과 중복되는 레코드가 DB에 저장되어.. 2025. 12. 1.
[토이프로젝트] KBO 경기 일정 수집하기(1) - 데이터 크롤링과 파싱(With 스프링부트 + Playwright) 목차/pages/KBO-경기-일정-수집하기-시리즈계기평소에 야구를 좋아하다 보니 경기 일정이나 결과를 데이터로 뭔가 해보면 어떨까 하는 생각이 들었습니다. 당장 데이터로 뭘 할지는 생각해보지 않았지만 그래도 일단 데이터를 수집해두면 뭐라도 하지 않을까 싶어 내친김에 시도해봤습니다. 처음에는 개발자 센터 같은곳에서 제공하는 API가 있나 찾아봤는데 아무래도 KBO는 개발자 센터나 오픈 API를 제공하지 않는 모양이더라구요. 그래서 KBO 공식 사이트를 크롤링하여 데이터를 수집해봐겠다는 생각을 하게 됐습니다.robots.txt 정책 확인 하기특정 웹사이트를 크롤링하려면 먼저 해당 사이트의 robots.txt 파일을 확인해서 크롤링을 허용하거나 허용하지 않는 경로를 확인해야 한다고 합니다. 물론 robots... 2025. 11. 25.
[Spring] String을 반환할 때 ResponseBodyAdvice로 공통 응답 포맷을 적용하면 발생하는 문제 해결해보기 목차들어가기 전에이전 글에서 String 타입을 반환하는 컨트롤러 메소드는 응답 본문을 작성할 때 StringHttpMessageConverter를 사용하기 때문에 ResponseBodyAdvice를 사용해서 공통 응답 포맷을 적용하기 어렵다는 내용을 다뤘습니다. 그래서 String 타입을 반환하는 컨트롤러 메소드는 공통 응답 적용 대상에서 제외하는 식으로 처리했죠. 잠깐 언급하고 넘어간 것처럼 String 타입을 반환하는 메소드에 공통 응답 포맷을 적용하는 방법이 있긴 합니다. 다만, 이 방법은 HTTP 응답이 작성되기 전에 컨트롤러 메소드의 반환값을 조작해야 하기 때문에 과정이 조금 복잡하죠. 이번에는 ResponseBodyAdvice를 사용해서 공통 응답 포맷을 적용할 때 String 타입을 반환하.. 2025. 4. 11.
[Spring] ResponseBodyAdvice를 사용해서 API에 공통 응답 포맷 적용하기 목차들어가기 전에프로젝트를 시작하게 되면 클라이언트가 서버에서 받은 응답을 원활하게 처리하도록 하기 위해 공통 응답으로 사용할 JSON 포맷을 정해서 봉투 패턴을 사용하는 경우가 많습니다.공통 응답 포맷을 적용하기 위해 컨트롤러 메소드의 반환 타입을 모두 공통 응답 DTO로 작성하게 됩니다. 문제는 컨트롤러 메소드를 작성할 때마다 매번 반환 객체를 공통 응답 DTO로 감싸줘야 해서 귀찮기도 하고, 실수로 누락할 수도 있다는 거죠. 그러다보니 자연스럽게 전역적으로 처리할 수 있을지 고민하게 됩니다. 이럴 때 사용할 수 있는 ResponseBodyAdvice에 대해 알아봅시다. 본문의 내용에서 다루는 코드는 Github 레포지토리에서 확인하실 수 있습니다.ResponseBodyAdviceResponseBod.. 2025. 2. 25.
[Spring Scheduler] 서버 이중화 또는 증설 시 ShedLock을 사용하여 스케쥴러 중복 실행 방지하기 목차들어가기 전에여러가지 이유로 구동되고 있는 서버를 증설해야 하는 경우가 있습니다. 이렇게 서버가 증설되어 여러 대의 서버 인스턴스에서 동일한 서버 애플리케이션이 구동되고 있다면 스케쥴러를 통해 정해진 시간에 주기적으로 동작하는 로직은 여러 서버에서 동시에 실행되었을 때 문제가 발생할 수 있기 때문에 오직 하나의 서버에서만 스케쥴러 작업이 수행되도록 하는 것이 좋습니다. 이번 포스트에서는 오픈 소스 라이브러리인 ShedLock을 사용하여 스프링 애플리케이션의 스케쥴러가 중복으로 실행되지 않도록 방지하는 내용을 다루고자 합니다.ShedLock?ShedLock은 MongoDB, Redis, RDBMS 등의 외부 저장소를 사용하여 다른 노드나 스레드에서 동일한 스케쥴러 작업이 중복 실행되지 않도록 해주는 오.. 2024. 9. 9.
[Spring/Spring Boot] 파일 다운로드와 multipart/form-data 업로드 컨트롤러 메소드 테스트 코드를 작성해보자 목차들어가기 전에최근에 파일을 다운로드 받는 컨트롤러 메소드와 파일을 업로드해서 처리하는 컨트롤러 메소드를 작성하면서 해당 컨트롤러 메소드가 제대로 돌아가는지 확인하려고 테스트 코드를 작성할 일이 있었습니다. 평소에 작성하는 테스트 코드는 평범한 요청과 응답을 가지는 로직에 대한 테스트 코드 뿐이었다 보니 파일 업로드/다운로드와 관련된 테스트 코드를 작성한다는게 상당히 생소했는데 나중에 까먹지 않으려고 기록해두려고 합니다. 본문상의 코드는 모두 코틀린으로 작성되어 있긴 하지만 가장 중요한 파일 업로드나 다운로드 검증 부분은 자바도 별반 다르지 않습니다.파일 업로드 테스트일반적으로 파일을 업로드하는 로직은 MultipartFile을 사용하는 경우가 많습니다. 이를 테스트하기 위해 스프링에서는 Multipa.. 2024. 8. 14.
[MockMvc] MockMvc 테스트 시 한글이 깨져서 테스트에 실패하는 문제 목차문제의 상황Spring REST Docs를 공부해보기 위해 이전에 작성했던 코드의 컨트롤러 테스트 코드를 MockMvc를 사용해서 작성하고 있었다.@SpringBootTest@AutoConfigureMockMvc@AutoConfigureRestDocsclass AdminControllerTest @Autowired constructor( private val tokenProvider: TokenProvider, private val memberRepository: MemberRepository, private val mockMvc: MockMvc, private val objectMapper: ObjectMapper = ObjectMapper()) { @Test fun.. 2024. 6. 19.
[Spring Boot] 스프링 인터셉터(Spring Interceptor)를 활용해서 API 로그를 DB에 기록해보자 목차 들어가기 전에 이전 포스트에서 AOP를 사용해서 API 로그를 기록하는 내용을 다뤘는데 이런 이야기를 들었다. 사실 지금까지 프로젝트를 진행하는 동안 인터셉터를 구현해서 사용했던 적이 없다보니 컨트롤러들에 공통으로 적용하는 로직은 익숙한 AOP로 구현했다. 그런데 인터셉터도 어쨌든 요청과 응답을 가로채서 일련의 행동을 수행하니까 인터셉터로 구현하는 것도 괜찮겠다는 생각이 들었다. 그래서 이번에는 스프링 인터셉터를 활용해서 API 로그를 기록해보려고 한다. 스프링 인터셉터는 어떻게 구성되는가? 스프링 인터셉터는 보통 HandlerInterceptor를 구현하는 별도의 클래스를 작성해서 구현한다. HandlerInterceptorAdapter를 상속받는 방법은 스프링부트 2.4(스프링 5.3)부터 De.. 2024. 3. 1.