redis config 수정

This commit is contained in:
2025-12-09 10:33:31 +09:00
parent a287ccd91a
commit 2e6c11ee64
3 changed files with 36 additions and 52 deletions

View File

@@ -1,4 +1,4 @@
package com.kamco.cd.kamcoback.code.util; package com.kamco.cd.kamcoback.common.utils;
import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.Basic; import com.kamco.cd.kamcoback.code.dto.CommonCodeDto.Basic;
import com.kamco.cd.kamcoback.code.service.CommonCodeService; import com.kamco.cd.kamcoback.code.service.CommonCodeService;
@@ -81,7 +81,7 @@ public class CommonCodeUtil {
* 상위 코드와 하위 코드로 공통코드명 조회 * 상위 코드와 하위 코드로 공통코드명 조회
* *
* @param parentCode 상위 코드 * @param parentCode 상위 코드
* @param childCode 하위 코드 * @param childCode 하위 코드
* @return 공통코드명 * @return 공통코드명
*/ */
public Optional<String> getCodeName(String parentCode, String childCode) { public Optional<String> getCodeName(String parentCode, String childCode) {
@@ -113,10 +113,10 @@ public class CommonCodeUtil {
try { try {
List<Basic> allCodes = commonCodeService.getFindAll(); List<Basic> allCodes = commonCodeService.getFindAll();
return allCodes.stream() return allCodes.stream()
.filter(code -> parentCode.equals(code.getCode())) .filter(code -> parentCode.equals(code.getCode()))
.findFirst() .findFirst()
.map(Basic::getChildren) .map(Basic::getChildren)
.orElse(List.of()); .orElse(List.of());
} catch (Exception e) { } catch (Exception e) {
log.error("상위 코드 기반 하위 코드 조회 중 오류 발생: {}", parentCode, e); log.error("상위 코드 기반 하위 코드 조회 중 오류 발생: {}", parentCode, e);
return List.of(); return List.of();
@@ -127,7 +127,7 @@ public class CommonCodeUtil {
* 코드 사용 가능 여부 확인 * 코드 사용 가능 여부 확인
* *
* @param parentId 상위 코드 ID * @param parentId 상위 코드 ID
* @param code 확인할 코드값 * @param code 확인할 코드값
* @return 사용 가능 여부 (true: 사용 가능, false: 중복 또는 오류) * @return 사용 가능 여부 (true: 사용 가능, false: 중복 또는 오류)
*/ */
public boolean isCodeAvailable(Long parentId, String code) { public boolean isCodeAvailable(Long parentId, String code) {
@@ -140,7 +140,7 @@ public class CommonCodeUtil {
ApiResponseDto.ResponseObj response = commonCodeService.getCodeCheckDuplicate(parentId, code); ApiResponseDto.ResponseObj response = commonCodeService.getCodeCheckDuplicate(parentId, code);
// ResponseObj의 flag 필드를 통해 SUCCESS/FAIL 확인 // ResponseObj의 flag 필드를 통해 SUCCESS/FAIL 확인
return response.getFlag() != null return response.getFlag() != null
&& response.getFlag().equals(ApiResponseDto.SuccFailCode.SUCCESS); && response.getFlag().equals(ApiResponseDto.SuccFailCode.SUCCESS);
} catch (Exception e) { } catch (Exception e) {
log.error("코드 중복 확인 중 오류 발생: parentId={}, code={}", parentId, code, e); log.error("코드 중복 확인 중 오류 발생: parentId={}, code={}", parentId, code, e);
return false; return false;

View File

@@ -3,11 +3,8 @@ package com.kamco.cd.kamcoback.config;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.BasicPolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.time.Duration; import java.time.Duration;
import java.util.List;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
@@ -45,6 +42,9 @@ public class RedisConfig {
return new LettuceConnectionFactory(redisConfig); return new LettuceConnectionFactory(redisConfig);
} }
/**
* Redis에서 사용할 공통 ObjectMapper
*/
@Bean @Bean
public ObjectMapper redisObjectMapper() { public ObjectMapper redisObjectMapper() {
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
@@ -56,61 +56,45 @@ public class RedisConfig {
return objectMapper; return objectMapper;
} }
/**
* 공통 Serializer (Template + Cache 둘 다 이거 사용)
*/
@Bean @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { public GenericJackson2JsonRedisSerializer redisSerializer(ObjectMapper redisObjectMapper) {
return new GenericJackson2JsonRedisSerializer(redisObjectMapper);
}
@Bean
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory connectionFactory,
GenericJackson2JsonRedisSerializer redisSerializer) {
RedisTemplate<String, Object> template = new RedisTemplate<>(); RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory); template.setConnectionFactory(connectionFactory);
// Key는 String으로 직렬화
template.setKeySerializer(new StringRedisSerializer()); template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer()); template.setHashKeySerializer(new StringRedisSerializer());
// Value는 JSON으로 직렬화 (JavaTimeModule 포함) template.setValueSerializer(redisSerializer);
GenericJackson2JsonRedisSerializer serializer = template.setHashValueSerializer(redisSerializer);
new GenericJackson2JsonRedisSerializer(redisObjectMapper());
template.setValueSerializer(serializer);
template.setHashValueSerializer(serializer);
template.afterPropertiesSet(); template.afterPropertiesSet();
return template; return template;
} }
// 기본 레디스 캐시 세팅
@Bean @Bean
public CacheManager cacheManager(RedisConnectionFactory connectionFactory) { public CacheManager cacheManager(
ObjectMapper cacheObjectMapper = new ObjectMapper(); RedisConnectionFactory connectionFactory,
cacheObjectMapper.registerModule(new JavaTimeModule()); GenericJackson2JsonRedisSerializer redisSerializer) {
cacheObjectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
cacheObjectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 알 수 없는 타입에 대해 더 유연하게 처리
cacheObjectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS);
cacheObjectMapper.findAndRegisterModules();
// 타입 정보 포함 - JAVA_LANG_OBJECT로 제한적으로 적용
// 호환성 문제 해결을 위해 더 많은 타입 허용
PolymorphicTypeValidator ptv =
BasicPolymorphicTypeValidator.builder()
.allowIfSubType("com.kamco.cd.kamcoback")
.allowIfSubType("org.springframework.data.domain")
.allowIfSubType("java.util")
.allowIfSubType("java.time")
.allowIfSubType("java.lang")
.allowIfBaseType(List.class)
.allowIfBaseType("com.kamco.cd.kamcoback.code.dto.CommonCodeDto$Basic")
.build();
cacheObjectMapper.activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT);
GenericJackson2JsonRedisSerializer serializer =
new GenericJackson2JsonRedisSerializer(cacheObjectMapper);
RedisCacheConfiguration config = RedisCacheConfiguration config =
RedisCacheConfiguration.defaultCacheConfig() RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofHours(1)) // 기본 TTL 1시간 .entryTtl(Duration.ofHours(1)) // 기본 TTL 1시간
.serializeKeysWith( .serializeKeysWith(
RedisSerializationContext.SerializationPair.fromSerializer( RedisSerializationContext.SerializationPair.fromSerializer(
new StringRedisSerializer())) new StringRedisSerializer()))
.serializeValuesWith( .serializeValuesWith(
RedisSerializationContext.SerializationPair.fromSerializer(serializer)); RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer));
return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).build(); return RedisCacheManager.builder(connectionFactory).cacheDefaults(config).build();
} }

View File

@@ -52,7 +52,7 @@ public class MembersService {
// salt 생성, 사번이 salt // salt 생성, 사번이 salt
String salt = String salt =
BCryptSaltGenerator.generateSaltWithEmployeeNo(updateReq.getEmployeeNo().trim()); BCryptSaltGenerator.generateSaltWithEmployeeNo(updateReq.getEmployeeNo().trim());
// 패스워드 암호화, 초기 패스워드 고정 // 패스워드 암호화, 초기 패스워드 고정
String hashedPassword = BCrypt.hashpw(updateReq.getPassword(), salt); String hashedPassword = BCrypt.hashpw(updateReq.getPassword(), salt);