Type Conversion

2024. 10. 9. 21:23Spring Framework/Web on Servlet Stack

Spring MVC에서는 요청에서 전달된 문자열 기반 입력(@RequestParam, @RequestHeader, @PathVariable 등)을 처리할 때 다양한 유형으로 변환할 수 있는 기능을 제공합니다. 이를 통해 클라이언트에서 전달된 데이터를 적절한 자바 타입으로 변환하여 사용할 수 있습니다.

타입 변환은 요청 파라미터를 해당 메서드의 아규먼트 타입으로 변환하는 과정입니다. 이 과정은 Spring에서 자동으로 수행되며, 기본적으로 지원되는 타입은 다음과 같습니다.

  • 기본 타입: int, long, double
  • 날짜/시간 타입: Date, LocalDate, LocalDateTime
  • UUID: UUID

타입 변환 동작

  1. 기본 설정:
    • Spring은 기본적으로 제공되는 변환기(converter)를 사용하여 문자열을 다른 타입으로 변환합니다.
    • 이때 변환이 실패하면 ConversionFailedException이 발생합니다.
  2. 빈 문자열 처리:
    • 빈 문자열("")은 변환 후 null로 간주됩니다.
    • 예를 들어, Long 타입 아큐먼트에 빈 문자열을 전달하면 null로 변환됩니다.
    • 이러한 경우, 아규먼트가 필수인 경우(required = true)에는 MissingServletRequestParameterException이 발생할 수 있습니다.
  3. @Nullable 사용:
    • 아규먼트를 null로 허용하려면 해당 아규먼트를 @Nullable로 표시하거나, @RequestParam 등의 애너테이션에서 required = false로 설정해야 합니다.
  4. Spring 5.3 이후의 변경 사항:
    • Spring 5.3부터는 non-null 아규먼트가 타입 변환 후에도 유지됩니다. 따라서, null 값을 허용하려면 @Nullable을 사용해야 하며, 이는 필수 아규먼트로 요구되는 경우에 발생할 수 있는 오류를 방지하는 모범 사례입니다.

샘플 코드

아래는 위의 내용을 기반으로 한 샘플 코드입니다.

1. 기본 타입 변환
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TypeConversionController {

    @GetMapping("/convert")
    public String convertType(@RequestParam int id, @RequestParam String name) {
        return "ID: " + id + ", Name: " + name;
    }
}

위 코드에서 id 파라미터는 정수로 변환됩니다. 클라이언트에서 /convert?id=10&name=John와 같은 요청을 보내면, Spring은 id를 정수로 변환하고 name을 문자열로 변환합니다.

2. 빈 문자열 처리
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class NullableController {

    @GetMapping("/nullable")
    public String handleNullable(@RequestParam(required = false) Long id) {
        if (id == null) {
            return "ID is null or not provided";
        }
        return "ID: " + id;
    }
}

이 예제에서는 id가 제공되지 않거나 빈 문자열일 경우 null로 변환됩니다. 따라서 클라이언트가 /nullable?id=로 요청하면 "ID is null or not provided"라는 응답을 받습니다.

3. @Nullable 사용 예제
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.lang.Nullable;

@RestController
public class NullableExampleController {

    @GetMapping("/nullableExample")
    public String example(@RequestParam @Nullable Long id) {
        if (id == null) {
            return "ID is null";
        }
        return "ID: " + id;
    }
}

위 코드에서 @Nullable을 사용하여 id가 null일 수 있음을 명시합니다. 이 경우 클라이언트에서 id를 제공하지 않으면 "ID is null"이라는 응답을 받게 됩니다.

4. 사용자 정의 변환기

타입 변환을 사용자 정의하려면 WebDataBinder를 사용하거나 FormattingConversionService에 포맷터를 등록할 수 있습니다.

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.Locale;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new StringToCustomTypeConverter());
    }

    public static class StringToCustomTypeConverter implements Converter<String, CustomType> {
        @Override
        public CustomType convert(String source) {
            return new CustomType(source); // 변환 로직
        }
    }

    public static class CustomType {
        private String value;

        public CustomType(String value) {
            this.value = value;
        }

        // Getter 및 기타 메서드
    }
}

이 코드는 문자열을 CustomType으로 변환하는 사용자 정의 변환기를 등록합니다.

타입 변환은 Spring MVC에서 요청 파라미터를 처리하는 중요한 부분입니다. 자동 변환 기능을 통해 클라이언트 요청을 적절한 자바 타입으로 변환할 수 있으며, 빈 문자열 처리, null 값 허용 등을 통해 더욱 유연한 코드를 작성할 수 있습니다. 필요한 경우 사용자 정의 변환기를 등록하여 특정 타입의 변환 로직을 정의할 수도 있습니다.

<참고> : https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-methods/typeconversion.html

'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글

Functional Endpoints Overview  (0) 2024.10.13
Annotated Controllers  (0) 2024.10.09
Return Values  (0) 2024.10.09
Method Arguments  (0) 2024.10.09
Handler Method  (0) 2024.10.09