[Spring] DTO 매핑시 특정 키만 null 값
·
JAVA/Application
나머지 값들은 다 정상적으로 매핑되어 값이 잘 들어가는데, 특정 키만 null로 들어가는 것을 발견했다.원인은 필드명이었다. 아래 글 덕분에 알게 되었다. https://bcp0109.tistory.com/309 Spring Request DTO 에 null 값이 들어가는 이유 (Jackson, Lombok)Overview Spring Boot 로 REST API 를 테스트 하다가 이상한 이슈에 직면했습니다. 클라이언트에서 @RequestBody 로 요청을 받기 위한 DTO 클래스를 만들고 값을 입력 받았는데 null 값이 입력되는 겁니다. 처bcp0109.tistory.com  문제가 되는 필드명은 cId였다. 소문자 하나 다음에 바로 대문자가 나오는 필드명이 문제가 되는 것이다. Spring은 htt..
[Spring AOP] Consumer onMessage() 비동기 수신 로깅
·
JAVA/Application
■ AOP를 통해 onMessage() 비동기 수신 로깅 Redis가 Consume할 때 호출되어 작업을 처리하기 시작하는 부분인 onMessage() 메서드를 AOP를 통해 로깅하려는 상황이었다. 기능 구현을 위한 샘플 코드를 짜서 테스트해보았다. 구조는 이러하다. - ConsumerFactory: 메시지를 구독할 컨슈머들을 생성 - StreamListenerImpl: 구독한 메세지를 처리할 onMessage 구현 - ListenContainer: 위 리스너를 관리할 컨테이너 설정 - LoggingAspect: 테스트 대상인 Aspect들 - RedisConfig: 기본 레디스 설정 *참고: ListenerContainer, Listener, 그리고 Consumer 객체간의 관계를 이해하는 것이 필요하..
[Redis] cannot deserialize from Object value (SerializationException)
·
JAVA/Application
Springboot Cache를 적용하고자 할 때 발생가능한 오류입니다.- 저는 redis cache 사용했습니다.- 또한 캐시 value에 대해서 GenericJackson2JsonRedisSerializer를 적용했습니다. 서버에 캐시를 적용했는데 만약 이런 에러를 만났다면, jackson의 역직렬화에 대해 생각해봅시다.캐시된 응답을 올바른 객체로 내보내야 하는데 역직렬화할때 쓸 생성자가 없다면cannot deserialize from Object value를 로그에서 만날 수 있습니다.*생성자의 존재 문제가 아닌, 역직렬화하기 적절한 생성자를 두는 것이 핵심입니다.org.springframework.data.redis.serializer.SerializationException: Could not ..
다량의 이미지 업로드 속도 최적화 / 트래픽 대비 / 비동기 처리
·
JAVA/Application
■ 리뷰등록시 문제 가능성너무나도 희망찬 이야기겠지만,만약 우리 서비스의 인기가 폭발해서동시에 많은 유저가 사진리뷰를 업로드한다면 어떨까? 동기적으로 처리할경우 대용량 사진 업로딩이 하나라도 있다면, 뒤를 이을 수많은 업로딩이 블로킹되며 작업이 주르륵 지연된다. 그래서 이때는 비동기 처리를 생각해야 한다.  이 상황을 대비하고자 하여..문제의 코드를 수선해봤다.  ■ 성능 측정 (TPS)2초 안에 25건의 스레드(사용자)를 실행함 (= 약 0.08초마다 스레드를 순차 실행)각 스레드(사용자)는 요청을 총 4개 보냄(= 총 100건의 요청을 보내는 테스트) □ 변경 이전  □ 변경 이후전반적으로 TPS도 상승하고,처리시간도 약 0.65배로 단축했다.  □ 비동기 + Multipart 관련 문제 해결사진 업..
[Redis] StreamListener(onMessage)와 Consumer 객체간 관계
·
미분류글
□ IntroSpringboot와 Redis를 통하여 메시지 비동기 처리를 할 때 StreamListener와 Consumer를 만나게 된다. 내가 원하는 구독자시스템, Pub/Sub, 메시지 처리 구조를 만들기 위해서는 StreamListenerContainer와 StreamListener, 그리고 Consumer 객체 사이의 관계를 이해하는 것이 필요하다.□ StreamListener와 Consumer의 관계 이해하기 StreamListener와 Consumer는 1:1로 연결을 맺고 있는 구조다.StreamListener와 Consumer가 관계지어지면 Subscription 객체를 생성한다. 아래 구조는,각 Consumer가 서로 다른 StreamListener와 맺어져 있고,이에 따라 서로 다른..
Redis Stream의 구조적 특징(Message Queue)
·
미분류글
1. Redis Stream 개요소개Redis 5.0에서 주요한 기능으로 등장했다. ( 18년 10월)Message Queue (MQ)로 사용할 수 있는 스택 중 하나이다.   Redis Stream MQ는 이런 특징을 가진다. (Rabbit MQ, Active MQ도 마찬가지)- 중복 없이 동시처리 가능- 재처리 가능 이 특징들은 Redis Stream 구조에서 기인한다.1. 중복 없이 동시처리 가능한 이유는 consumer group이 single stream을 두고 메시지를 각 consumer가 하나씩 빼와서 처리하기 때문이다.2. 재처리가 가능한 이유는 메시지마다 id를 두고 관리하며, ACK 명령을 통해 메시지 처리완료를 지원하고, 만약 ACK를 받지 못한 메시지는 PENDING 처리하기 때문이..
[Java] ObjectMapper에 TypeReference를 사용할 때
·
JAVA
TypeReferenceJackson 라이브러리를 사용하여 JSON을 역직렬화할 때, 제네릭 타입 정보를 보존하기 위해 사용한다.  ∨ ObjectMapper.readValue() 에서 안전한 매핑 가능ObjectMapper.readValue(arg, type) 의 두번째 인자에 타입정보를 표기할 수 있다.변환대상인 arg를 어떤 타입으로 매핑할 것인가의 정보를 주는 것이다. 만약 json을 어디선가 받아와서 변환하고 싶다면, type에는 Class 타입 또는 TypeReference가 온다.특히 TypeReference를 ObjectMapper에 사용하면 경고(ClassCastException 발생 가능 경고)가 나지 않게 할 수 있다.mapper.readValue(json, ArrayList.clas..
[Java] Generic Type erasure / 제네릭 타입 소거
·
JAVA
Generic Type erasure자바에서 Generic Type erasure 프로세스는 말 그대로 제네릭 타입을 지워버리는 프로세스다. 자바에서 제네릭은 런타임에 소거된다. 제네릭은 타입 검사 이점이 있으므르 컴파일때 타입 검사를 보장한다. 그러나 런타임에는 타입 정보를 삭제한다.  런타임에 타입을 삭제한다?모든 타입을 Object 타입으로 바꾼다.또는 명시된 바운드로 바꾼다. 즉 컴파일 / 런타임 때 아래와 같이 다르다.// 컴파일시 타입 체크public class Test { public void test(T test) { ... }}// 타입 소거가 된 런타임public class Test { public void test(Object test) { ...
[IntelliJ] 폐쇄망 개발환경 세팅
·
미분류글
■ Intro일반적인 네트워크에서 springboot 프로젝트를 세팅할때는intellij가 필요한 gradle을 자동으로 설치해서 문제가 없었다. 그러나 사내망에서는 gradle 설치 100% 시점에서 차단이 되는 것을 확인할 수 있다.gradle 설치파일을 어떻게 가져와서 잘 잡아도 아래 두 문제가 발생 가능하다.- build.gradle에서 distributionUrl에 접근하지 못하는 문제가 있어서 조금 변경해줘야 함- root 인증서를 jdk keystore에 등록해주어야 함 그래서 해결 방법을 기록해둔다. ■  요약- 필요한 버전의 gradle 수동설치를 해야 한다. 초기세팅할 시점에 Settings에서 gradle을 확인했을 때 Use Gradle From이 gradle-wrapper.prop..
상시 업데이트함 -- Effective java 스터디
·
JAVA/Effective Java
(24.07.00) ItemXX: ~~~ ~~  (24.07.00) Item77: 예외를 무시하지 말라~~   (24.07.00) Item76: 가능한 한 실패 원자적으로 만들라~~   (24.07.00) Item75: 예외의 상세 메시지에 실패 관련 정보를 담으라~~    (24.07.00) Item74: 메서드가 던지는 모든 예외를 문서화하라~~   (24.07.22) Item73: 추상화 수준에 맞는 예외를 던지라 ## 예외 번역이란너무 저수준 예외를 계속 전파하면, 내부 구현 방식도 드러나고 혼란스러워진다. 그래서 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다.try { ...} catch (LowerLevelException e) { // 추상..