Spring
-
ObjectMapper LocalTime등 날짜시간 타입 매핑 실패 해결법Spring/Trouble Shooting 2024. 1. 13. 01:21
문제 상황 테스트 코드 작성중에 void createOperatingTime() throws Exception { //given AnimalHospital savedAnimalHospital = getSavedAnimalHospital(); List requests = new ArrayList(); for (DayOfWeekStatus value : DayOfWeekStatus.values()) { HospitalOperationTimeCreateRequest hospitalOperationTimeCreateRequest = HospitalOperationTimeCreateRequest.builder() .dayOfWeekStatus(value.name()) .startTime(LocalTime.of(1..
-
QueryDsl 거리 검색 쿼리 최적화Spring/Trouble Shooting 2023. 12. 9. 16:20
개요 사이드 프로젝트를 진행하면서 검색 API 구현을 담당하였다. 개인 프로젝트등에서는 단순 키워드를 통한 검색을 구현 하였지만 본 프로젝트에서는 정보 제공의 목적으로 거리를 계산해서 제공을 해야하는 상황이 발생했다. 이를 해결하는 과정을 기록으로 남겨두어 나중에 비슷한 상황이 발생하면 다시 참고해보는 용도로 해당 글을 작성한다. 문제 요구사항 해당 문제 상황에서 고려되는 사항은 다음 두 가지가 있었다. 유저의 위도, 경도가 주어지면 해당 건물에 대한 거리가 출력되어야한다. 유저의 위도, 경도가 주어지면 거리순 정렬이 되어야한다. 문제 인식 다른 요구사항에는 적절하게 구현이 완성된 상태였다. 기본적인 QueryDsl을 사용해서 값만 매칭시켜두면 해결되는 문제였기에 큰 어려움은 없었다. 다만 해당 문제를 ..
-
ReflectionTestUtils를 활용한 단위 테스트, 객체의 ID 설정하기Spring/Trouble Shooting 2023. 11. 19. 01:21
문제 상황 질문의 번호와 유저의 번호를 받고, 질문의 작성자 번호가 유저의 번호와 같다면 삭제하는 과정이다. public void deleteById(Long questionId, Long memberId) { Question question = findById(questionId); if (validateQuestionWriter(memberId, question)) { questionRepository.deleteById(questionId); } } private Boolean validateQuestionWriter(Long memberId, Question question) { return question.getMember().getId().equals(memberId); } 그다지 이해하기 어..
-
QueryDsl 페이징 최적화 PageImpl vs PageableExecutionUtils 차이Spring/Study 2023. 11. 14. 01:07
PageImpl vs PageableExecutionUtils return PageableExecutionUtils.getPage(result, pageable, countQuery::fetchOne); return new PageImpl(result, pageable, count); 둘의 차이는 무엇일까? 상황 예시 24개의 content가 존재한다고 가정해보자 PageSize = 10 이라고 하면 페이지는 1,2,3 페이지가 존재하게 된다. 1, 2 페이지에서는 10개의 content가 채워져서 페이지 result가 반환되기 때문에 PageImpl, PageableExecutionUtils 둘 다 count 쿼리가 발생한다. 그런데 3페이지 마지막 페이지에서는 차이가 발생한다. 3페이지에서는 4개의 ..
-
Spring Test 환경에서 Audit 적용이 안될 때Spring/Trouble Shooting 2023. 11. 13. 17:13
상황 도메인의 설계 구조를 보고 가자 @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @EntityListeners(AuditingEntityListener.class) public class Question { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; //... @Embedded private AuditEntity auditEntity; //... @Builder public Question( //.. ) //... this.auditEntity = new AuditEntity(); } } Question이라는 도메인에 AuditEntity를 ..
-
Docker 컨테이너 환경에서 Eureka Client 등록시 ip 문제Spring/Trouble Shooting 2023. 11. 7. 00:41
문제 상황 Eureka 클라이언트를 등록하고 Spring Cloud Gateway를 통해 로드 밸런싱 처리를 하도록 설정해뒀다. 하지만 로드밸런싱 처리는 되지 않았고 직접 ip 주소를 통해 요청을 할 때는 정상적으로 요청이 전달되고, Eureka Server에 등록된 클라이언트의 목록에는 이상이 없었다. 원인은? 문제는 Eureka Client가 등록될 때 클라이언트들이 외부 ip 기준으로 등록되는 것이 아니라, 내부 ip를 기준으로 등록되어 문제가 발생하는 것이였다. 원인은 배포 환경을 Docker를 통해 진행했는데, Eureka Client의 경우 컨테이너 환경에서 배포가 될 경우 알아서 실제 배포되는 ip로 등록되는 것이 아닌 내부 ip를 기준으로 등록되는 것이였다. 알아낸 방법 이를 알아낸 방법은..
-
H2-Console 접속 문제 해결Spring/Trouble Shooting 2023. 11. 6. 20:35
문제 상황 위와 같이 내장 H2 DB를 사용하여 접속하려 하는데 문제가 발생했다. 개발자 도구를 통해서 확인해보면X-Frame-Options이 문제인 것을 알 수있다. 해결 방법 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http ... .headers(headers -> headers.frameOptions(FrameOptionsConfig::disable)) ... .build(); } 최근 Security 버전이 변경되면서 함수형으로 선언하도록 바뀌었다. 따라서 위와 같이 선언해줘야 한다.
-
[Spring Boot] mockMvc를 통해 담겨오는 HttpOnly Cookie 내용물 검증하는 테스트 코드 작성법Spring/Study 2023. 7. 23. 23:10
JWT 토큰을 사용하여 로그인을 하면 Access토큰과 Refresh토큰을 응답으로 주는데, 이때 Refresh토큰을 HttpOnly 쿠키로 전달하는 상황이다. 프론트 측에서는 담겨오는 쿠키를 임의로 설정할 수 없으므로 좀 더 보안에 유리하다고 생각한다. 개발 단계에서 이를 검증하기 위해서 mockMvc를 통해 테스트 코드를 작성하는데 body에 담겨오는 값들은 jsonPath를 통해 검증을 진행할 수 있지만, 헤더에 담겨오는 HttpOnly 쿠키는 따로 옵션이 설정되어 값 + 옵션 값까지 동시에 전달된다. 그렇다면 테스트 코드를 어떻게 작성을 해야 하는가? 에 대한 해결 방법이다. 가장 먼저 테스트 코드는 given when then 패턴으로 작성하였다. when까지의 패턴 코드이다 when 까지의 코..