스프링

· TIL ✍️
문제토스페이먼츠 API를 이용하던 중, 응답으로 주던 날짜 형식 "2024-10-02T21:16:13+09:00" 이 LocalDateTime으로 파싱이 되지 않았다. 해결 OffsetDateTime을 이용해서 파싱 할 수 있었다.  1. LocalDateTime 파싱 에러 발생 @Test@DisplayName("LocalDateTime 파싱 - 에러남")public void testLocalDateTimeParseException() { // given String rawTime = "2024-10-02T21:16:13+09:00"; // when & then assertThatThrownBy(() -> LocalDateTime.parse(rawTime)) .isIns..
· TIL ✍️
문제간편결제를 구현하기 위해 6자리 숫자 비밀번호를 도입했다. 근데 평문으로 저장할 순 없으니 암호화를 해야 하는데, 스프링 시큐리티까지는 필요 없이 비밀번호 암호화만 하면 되었다. 해결 dependencies { // ... // spring security crypto implementation 'org.springframework.security:spring-security-crypto' // 여기 !!! // ...}spring-security-crypto 라이브러리를 의존한다. import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configur..
· TIL ✍️
문제결제 엔티티에서 결제 승인 메서드를 실행하면 결제 승인 시간에 자동으로 현재 시간으로 넣어준다. 자동으로 넣어준 LocalDateTIme을 어떻게 테스트할지 궁금했는데, 특정 시간과 가까운지 테스트하는 코드가 있었다.상황 /** * 결제 승인 */public void approve() { this.status = PaymentStatus.APPROVED; this.approvedAt = LocalDateTime.now(); // 여기 !!!}결제 승인 메서드 실행 시 approvedAt에 현재 시간을 넣어준다.해결 전체 테스트 코드import static org.assertj.core.api.Assertions.assertThat;// ... @Test@DisplayName("결제 성공")..
· TIL ✍️
문제우리는 JPA 엔티티를 Ksuid라고 하는 고유 식별자를 사용하기로 했다. UUID 같은거다.  생성시간 기반의 20byte 고유 식별자로, 시간순으로 정렬이 가능해서 인덱싱의 이점을 누리면서도 랜덤값도 포함되어 중복 가능성이 거의 없으며, 길이도 짧다.  따라서 엔티티를 저장할 때 id를 넣어서 생성하도록 했다.  @Transactionalpublic S save(S entity) { Assert.notNull(entity, "Entity must not be null"); if (this.entityInformation.isNew(entity)) { this.entityManager.persist(entity); return entity; } else {..
· TIL ✍️
문제멀티 모듈 구조에서 JpaRepository 빈을 읽어오지 못하는 문제가 있었다. 상황우리는 멀티 모듈을 채택했고, 스프링 앱, 도메인 코어, 데이터베이스 모듈로 3개를 분리했다. 스프링 앱에서 실행 시, 데이터베이스 모듈의 JpaConfig 설정을 읽어오지 못해서 도메인 코어의 repository에 JpaRepository를 빈이 없다고 주입을 못해주고 있었다.   간단하게 현제 문제인 것들만 정리하자면모듈payment-core : 결제 도메인의 핵심 부분 (서비스, 도메인, 리포지토리 포함)모듈 위치 : service:payment:core 패키지 시작점 : radiata.service.payment.corepayment-api : 결제 도메인의 외부 요청 부분 (스프링 애플리케이션, 컨트롤러, ..
· TIL ✍️
// application.ymlspring: application: name: ymlserver: port: 8088fruit: list: - name: banana color: yellow - name: apple color: reddeveloper: name: yunjaeapplication.yml // application-dev.ymlserver: port: 8055application-dev.yml  // DeveloperName.class import lombok.Data;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframewor..
· TIL ✍️
문제 스프링 부트에서 Record 클래스로 application.yml 파일 값 가져오려다가 에러가 났다. 상황// application.yml fruit: list: - name: banana color: yellow - name: apple color: red yml 파일에 fruit.list 속에 과일 리스트가 있는 형태를 스프링에서 가져다 쓰려고 했다.  // Fruit.classpublic record Fruit( String name, String color) {} // FruitList.classimport org.springframework.boot.context.properties.ConfigurationProperties;impor..
· TIL ✍️
문제유레카 서버 설정을 위해 따로 EurekaServerConfig라고 하는 클래스를 만들어 실행했지만, 중복되는 빈객체로 실행이 되지 않았다. 상황@EnableEurekaServer@SpringBootApplicationpublic class EurekaApplication { public static void main(String[] args) { SpringApplication.run(EurekaApplication.class, args); }}강의 예제에는 애플리케이션 클래스 위에 붙여주었지만, 나는 애플리케이션에 덕지덕지 @Enable- 어노테이션을 붙이는 걸 좋아하지는 않아서 따로 ~Config 클래스를 만들어주기로 했다. @SpringBootApplicationpubl..
· TIL ✍️
상황 개인적으로 하는 프로젝트에서 AOP를 썼었다.  Refresh token을 쓰고 있었고, 이를 레디스에 저장하고 있었다. 토큰 속에는 닉네임을 subject 로 가지고 있었다.  문제는 닉네임을 수정하면 리프레쉬 토큰에는 변경이 되지 않아서 로그인이 안 되는 것. 그래서 레디스 속 리프레쉬 토큰을 변경해주어야 했고, 변경된 리프레쉬 토큰을 응답 쿠키에 담아주어야 했다.  또 유저 삭제 시에도 리프레쉬 토큰을 레디스에서 삭제하고, 응답 쿠키도 삭제해야했다.  이를 AOP로 구현한 코드는 아래와 같다. 간략하게 설명하면,@Pointcut 으로 각각 닉네임 수정 시점, 유저 삭제 시점 을 지정해주었고,@Around 로 수정 직후, 삭제 직후에 리프레쉬 토큰 처리를 해주었다. @Slf4j(topic = "..
yunjae62
'스프링' 태그의 글 목록 (2 Page)