[JAVA] JsonCreator, ConverterFactory로 enum 클래스 관리하기

jihun Choi·2023년 8월 14일
0
post-thumbnail

안녕하세요 오랜만에 돌아왔습니다 회사일이 바빠 오랜만에 글올리는점 양해 부탁드려요 ㅎㅎ 오늘은 enum 클래스를 JsonCreator(json) 어노테이션, ConverterFactory(queryString) 클래스로 enum 클래스를 관리해보도록 하겠습니다

@Getter
@RequiredArgsConstructor
public enum StatusTest{
	ALPPA("A"),
    BETTA("B"),
    GAMMA("C");
}

위의 코드와 같이 json으로 데이터를 백앤드단에서 받을때 ALPPA, BETTA, GAMMA로 받는것이 아닌 프론트 단에서 편리하도록 A, B, C 이러한 형태로 받아야 할때가 있습니다 이때 JsonCreator 어노테이션과 ConverterFactory 클래스를 사용하면 보다 편하게 처리해줄수 있습니다

  • JsonCreator 어노테이션

    JsonCreator 어노테이션을 사용하여 json데이터로 enum 타입이 넘어왔을 때 string to enum converter 처리를 해줄 수 있습니다

@Getter
@RequiredArgsConstructor
public enum StatusTest{
	ALPPA("A"),
    BETTA("B"),
    GAMMA("C");
    
    private final String status;
    
    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static StatusTest from(@JsonPropety("status") String status){
    for(StatusTest statusTest : StatusTest.values()){
    	if(status.equalsIgnoreCase(StatusTest.getStatus()){
        	return statusTest;
        }
        return null;
    }
}
  • @JsonCreator란
    기본생성자 + setter 조합으로서 jackson이 해당 함수를 통해 객체를 생성하고 필드를 채워줌

위의 코드와 같이 enum타입 괄호안에 status를 선언하고 JsonCreator를 통해 받아온 String 타입을 enum타입으로 변환시켜주는 로직을 구현하였습니다

	###GET http://localhost/enumtest
    Content-Type : application/json
    
    {
    	statusTests : ["A", "B"]
    }

VO단에서 EnumSet으로 enum 클래스를 선언 후 인텔리제이에서 .http파일로 API를 테스트해보고 디버깅 결과 ALPPA, BETTA 값을 얻을수 있는것을 확인하였습니다

  • ConverterFactory 클래스 사용
    ConverterFactory 클래스 사용을 하여 queryString 방식으로 http통신을 할때 string to converter 처리 해줄수 있습니다
@Getter
@RequiredArgsConstructor
public enum StatusTest implements EnumMapperType{
	ALPPA("A"),
    BETTA("B"),
    GAMMA("C");
    
    private final String status;
    
    @JsonCreator(mode = JsonCreator.Mode.DELEGATING)
    public static StatusTest from(@JsonPropety("status") String status){
    for(StatusTest statusTest : StatusTest.values()){
    	if(status.equalsIgnoreCase(StatusTest.getStatus()){
        	return statusTest;
        }
        return null;
    }
    
    @Override
    public String getCode() {
        return name();
    }
}

EnumMapperType.java

public interface EnumMapperType {
    String getCode();
    String getStatus();
}
  • Enum 클래스 상속과 ConverterFactory에 사용할 인터페이스를 만들어줍니다

StringToEnumConverterFactory.java

package com.example.anotationEx.config;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class StringToEnumConverterFactory implements ConverterFactory<String, Enum<? extends EnumMapperType>> {
    @Override
    public <T extends Enum<? extends EnumMapperType>> Converter<String, T> getConverter(Class<T> targetType) {
        return new StatusCodeToEnumConverter<>(targetType);
    }

    private static final class StatusCodeToEnumConverter<T extends Enum<? extends EnumMapperType>> implements Converter<String, T> {

        private final Map<String, T> map;

        public IdCodeToEnumConverter(Class<T> targetEnum) {
            map = Arrays.stream(targetEnum.getEnumConstants())
                    .collect(Collectors.toMap(enumConstant -> ((EnumMapperType) enumConstant).getStatus(), Function.identity()));
        }

        @Override
        public T convert(String source) {
            //해당 값 존재 여부 확인
            if (!StringUtils.hasText(source)) {
                return null;
            }

            T value = map.get(source);
            if (value == null) {
                throw new IllegalArgumentException("IllegalArgumentException");
            }
            return value;
        }
    }
}
  • string 타입을 enum타입으로 변경 할 ConverterFactory를 구현해 줍니다

WebConfiguration.java

@Configuration
public class WebConfiguration implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        ConverterFactory converterFactory = new StringToEnumConverterFactory();
        registry.addConverterFactory(converterFactory);
    }
}

마지막으로 converterFactory를 FormatterResitry에 추가해주는 작업을 진행합니다 테스트 결과 정상적으로 출력되는것을 확인할 수 있었습니다 다음번엔 더 재미있는 소재로 찾아뵙겠습니다 감사합니다.

profile
성장을 위해 열심히 노력하는 개발자 입니다

1개의 댓글

comment-user-thumbnail
2023년 8월 14일

글 잘 봤습니다.

답글 달기