
Spring boot에서 통합 테스트를 진행하다가 아래 코드에서 에러가 발생했다. Error while extracting response for type [class com.tistory.rjvv.learntest.exception.format.ErrorResponse] and content type [application/json] org.springframework.web.client.RestClientException: Error while extracting response for type [class com.tistory.rjvv.learntest.exception.format.ErrorResponse] and content type [application/json] 내가 만든 ErrorRes..

오늘은 @Profile을 활용해서 환경별로 빈 주입을 다르게 하는 방법을 알아보도록 한다. 사내 서비스가 사외 서비스로 one-code로 오픈이 되는 경우가 있다. 그렇게 되면 상황별로 처리해야 하는 로직이 틀려질 수 있다. 이때 분기문으로 매번 처리를 하게 되면 코드가 지저분해질 뿐더러 테스트가 어려워지는 코드가 된다. 즉, 환경별로 담당하는 서로 다른 객체에 역할을 분리해주는 것이 더 나은 방법이다. 이때 다형성과 @Profile을 활용하면 보다 나은 방법으로 환경별 로직을 처리할 수 있다. 먼저 @Profile을 사용하지 않는 상황을 생각해보자. profile은 internal과 external이 있다고 가정한다. signIn()은 환경별로 로직이 달라지고, sendOtp()는 공통 로직으로 처리된..

Spring을 사용하면 많은 리소스를 관리하게 되는데, url, password, username 등의 데이터들은 노출이 되면 안된다. 그렇기 때문에 암호화를 해줘야 하는데, Jasypt라는 프로퍼티를 암호화해서 관리할 수 있다. 의존성 추가 com.github.ulisesbocchio jasypt-spring-boot-starter 3.0.4 암호화 프로퍼티 활성화 빈 주입 @Configuration public class JasyptConfigure { @Value("${jasypt.encryptor.password}") private String key; @Bean("jasyptStringEncryptor") public StringEncryptor stringEncryptor() { SimpleS..

보통 schema.sql, data.sql을 구성하거나, import.sql로 데이터를 초기화하는 방법이 있는데, 오늘은 spring boot 2.5부터 변경된 DB 데이터 초기화 설정으로 schema.sql과 data.sql을 다뤄보고자 한다. Spring boot 2.5 이전 spring: datasource: driver-class-name: org.h2.Driver url: jdbc:h2:~/test username: sa password: initialization-mode: always schema: classpath:schema.sql data: classpath:data.sql spring boot 2.5 이전에는 spring.datasoruce 프로퍼티에서 해당 데이터를 초기화하는 방법을..

실무에서 javax.validation의 어노테이션을 주로 사용했는데, 궁금한 점이 생겨서 간단하게 javax.validation을 의존성에 추가해줬다. javax.validation validation-api 2.0.1.Final @PostMapping("/send") public ResponseEntity send(@RequestBody @Valid Letter letter) { return ResponseEntity.ok(letter); } @Getter class Letter { @NotNull private String from; @NotBlank private String to; @Size(min = 10, max = 1000) private String contents; public Lett..

실무에서 보통 개발 환경별로 application profile을 분리한다. 현재 회사에서 사내망(dev, stg, prod), 사외망(dev, stg, prod)에서 각각의 yml로 설정을 분리하는 방식을 사용했다. 기능이 추가될수록 yml 파일은 커지고 누군가는 똑같이 맞추기 위해서 그대로 설정을 다른 yml에 붙여넣으면서 배보다 배꼽이 더 커지는 것을 보고 배꼽을 눌러주기 위해 profile 분리에 대해 공부하고 적용했다. 환경 MACBOOK AIR M1 Intellij ultimate spring boot 2.7 maven3 jdk17 기본적으로 local 환경에서 구동할 경우 어떤 환경으로 서버를 구동할지에 대한 설정이 필요하기 때문에 profiles.active 혹은 profiles.defau..

다크 모드에서 그림이 잘 보이지 않습니다. 라이트 모드에서 읽는 것을 추천합니다. 오늘의 목표는 스프링이 요청을 처리하는 내부적인 원리 이전에 서버가 클라이언트의 요청을 어떻게 처리하는지에 대한 큰 틀을 이해하는 것이다. Tomcat(WAS) Tomcat은 WAS(Web Application Server)의 대표적인 미들웨어 서비스이다. WAS는 웹 서버와 웹 컨테이너의 결합으로 다양한 기능을 컨테이너에 구현하여 다양한 역할을 수행할 수 있는 서버를 말한다. 클라이언트의 요청이 있을 때 내부의 프로그램을 통해 결과를 만들어내고 이것을 다시 클라이언트에 전달해주는 역할을 하는 것이 바로 웹 컨테이너이다. Flow Web server 웹 서버는 사용자가 웹 브라우저에서 URL 입력했을 때 사용자에게 응답을 ..

실무에서 API상 GET method를 사용하지만 list를 받아와야 했는데, Spring에선 일반적으로 RequestBody를 사용할 수 없었다. (HttpMessageNotReadableException) 물론, 조금 찾아본 바로는 2014년 후에 나온 RFC7230-7237 Spec을 확인해본 결과로 Request message framing is independent of method semantics, even if the method doesn't define any use for a message body 라는 문구가 추가됐는데, 이는 method 의미와 requestBody의 의미 체계는 독립적이라고 표현을 하는 것 같다. 평소처럼 List로 파라미터를 설정해서 값을 받았는데, 읽어오질 못..

MapStruct org.mapstruct package 안에 있는 매핑 라이브러리이다. 이 녀석도 아주 강력한 기능을 제공하는데, 어노테이션 기반으로 작성하기에 Spring을 했다면 더 쉬워지는 라이브러리이다. 특히, 리플렉션을 사용하지 않기 때문에 다른 동적 맵핑보다 시간 절약성, 컴파일 시간 안전성, 오류 내용 확인성 등에서 높은 우위를 가진다. 나는 MapStruct를 설정하는 과정이 귀찮기도 하고 lombok 어노테이션과 순서를 맞춰야 한다는 제약 때문에 그냥 사용하기 싫어진다... 설정 4.0.0 org.mapstruct mapstruct 1.4.2.Final org.projectlombok lombok 1.18.22 17 17 1.4.2.Final 1.18.22 org.apache.maven..

ModelMapper org.modelmapper package에 있는 객체 매핑 관련 라이브러리이다. 이 녀석은 아주 강력하고 지능적인 기능을 자랑한다. (사용법을 잘 알고 메서드들을 파악했다고 가정했을 때, 일단 나는 아님) 우선 장점부터 간략히 나열하자면, 매핑을 커스터마이징할 수 있다. 필드명이 달라도, 타입이 달라도 매핑 전략을 커스터마이징할 수 있는 기능을 제공하기 때문에 유연하게 객체를 매핑할 수 있다. 기본적으로 Getter/Setter기반으로 필드를 매핑하지만, 설정을 변경해서 Reflection으로 필드를 매핑할 수 있다. 엔티티 무결성을 지킬 수 있다는 장점이 있다. (물론, 특정 경우에는 단점이 있을 수 있다.) ModelMapper의 기능이 매우 다양하기 때문에 대략적인 기능들만 ..