Spring

[ Spring ] Request Param을 enum으로 받기

자바니또 2022. 3. 23. 15:23

요청 파라미터를 enum으로 변환하여 다루고 싶은 경우가 있습니다. 예를 들어 은행 코드와 같은 경우 004, 009와 같이 각 코드는 어떤 은행인지 알 수 있는 아이덴티티 역할을 합니다.

문자열과 enum의 이름이 같다면 자동으로 컨버팅해주지만 그렇지 않다면 다음과 같은 문제점이 있습니다.

  1. 휴먼 에러가 발생하기 쉽습니다.
  2. 프로젝트에 중간에 참여한 사람은 익숙하지 않아 알아보기 쉽지 않습니다.
  3. 별도의 유효성 체크가 필요합니다.

Spring에서는 문자열을 enum으로 변환해주는 컨버터를 직접 만들어 적용시킬 수 있습니다.

문제 상황 예시

요청 파라미터로 은행코드를 받아 거래내역을 조회 하는 상황을 예로 들어보겠습니다. enum을 사용하지 않는다면 다음과 같이 작성할 수 있습니다.

@GetMapping("/bank-transactions")
public Result getAllTransactionList(@RequestParam String bankCodeStr) {

    BankCode bankCode = bankCode = BankCode.of(bankCodeStr);    // enum으로 변환

    // .. 조회 로직 수행
}

public enum BankCode {
    KB("004", "국민은행"),
    NH("011", "농협은행");

   private final String code;
   private final String bankName;

   // 생성자 생략

   public static BankCode of(String codeStr) {
       if (code == null) {
           trhow new IllegalArgumentException();
       }

       for(BankCode bc : BankCode.values()) {
           if(bc.code.equals(codeStr) {
               return bc;
           }
       }

       throw new IllegalArgumentException("일치하는 은행코드가 없습니다.");
   }
}

문자열 은행코드를 받아서 컨트롤러에서 직접 변환해주도록 했습니다. 물론 이렇게 해도 한 줄 추가될 뿐 문제는 없습니다.

하지만 저는 여기서 만족할 수 없습니다. 은행코드를 입력받으면 자동으로 BankCode로 변환하여 받고 싶습니다.

Converter 생성

  1. org.springframework.core.convert.converter.Converter를 구현한 Converter 클래스를 만듭니다.
public class BankCodeRequestConverter implements Converter<String, BankCode> {
    @Override
    public BankCode convert(String bankCode) {
        return BankCode.ofCode(bankCode);
    }
}
  1. WebMvcConfigurer를 구현하고 addFormatters를 재정의 하여 만든 컨버터를 추가합니다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new BankCodeRequestConverter());
    }
}

이게 끝입니다. 위의 두 과정을 수행하면 Spring이 알아서 컨버터의 코드를 호출하여 변환해 줍니다. 즉, 다음과 같이 사용할 수 있습니다.

@GetMapping("/bank-transactions")
public Result getAllTransactionList(@RequestParam BankCode bankCode) {

    // .. 조회 로직 수행
}

직접 변환 작업을 처리하지 않아도 되기 때문에 코드가 좀 더 간결해 지는 효과가 있습니다.

꼭 enum으로 변환 할 때만 사용할 수 있는 것이 아니라 객체로 데이터를 받을 때 컨버터를 만들어 사용할 수 있습니다.

참고