-
타입 컨버터Java/SpringBoot 2022. 8. 18. 17:11
Spring Type Converter
@GetMapping("/hello-v2") public String helloV2(@RequestParam Integer data) { System.out.println("data = " + data); return "ok"; }
url의 파라미터로 들어올때의 data는 문자열 형식인데 스프링의 @RequestParam을 거치면 문자가 정수 형식으로 들어온다.
스프링이 중간에서 타입 변환을 해주기 때문이다.
컨버터 인터페이스 구현
package hello.typeconverter.converter; import lombok.extern.slf4j.Slf4j; import org.springframework.core.convert.converter.Converter; @Slf4j public class StringToIntegerConverter implements Converter<String, Integer> { @Override public Integer convert(String source) { log.info("convert source={}", source); return Integer.valueOf(source); } }
컨버전 서비스 인터페이스 - 테스트 코드
package hello.typeconverter.converter; import hello.typeconverter.type.IpPort; import org.junit.jupiter.api.Test; import org.springframework.core.convert.support.DefaultConversionService; import static org.assertj.core.api.Assertions.*; public class ConversionServiceTest { @Test void conversionService() { //등록 DefaultConversionService conversionService = new DefaultConversionService(); conversionService.addConverter(new StringToIntegerConverter()); conversionService.addConverter(new IntegerToStringConverter()); conversionService.addConverter(new StringToIpPortConverter()); conversionService.addConverter(new IpPortToStringConverter()); //사용 assertThat(conversionService.convert("10",Integer.class)).isEqualTo(10); assertThat(conversionService.convert(10,String.class)).isEqualTo("10"); IpPort ipPort = conversionService.convert("127.0.0.1:8080",IpPort.class); assertThat(ipPort).isEqualTo(new IpPort("127.0.0.1", 8080)); String ipPortString = conversionService.convert(new IpPort("127.0.0.1",8080), String.class); assertThat(ipPortString).isEqualTo("127.0.0.1:8080"); } }
스프링에 Converter 적용 - WebConfig 추가
package hello.typeconverter; import hello.typeconverter.converter.IntegerToStringConverter; import hello.typeconverter.converter.IpPortToStringConverter; import hello.typeconverter.converter.StringToIntegerConverter; import hello.typeconverter.converter.StringToIpPortConverter; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToIntegerConverter()); registry.addConverter(new IntegerToStringConverter()); registry.addConverter(new StringToIpPortConverter()); registry.addConverter(new IpPortToStringConverter()); } }
Formatter
화면에 숫자를 표시할 때 쉼표를 넣거나 날짜 객체를 지정한 형식에 맞게 출력하도록 할 때 사용한다.
Locale
날짜, 숫자의 표현방법에 현지화 정보가 사용될 수 있다.
Formatter interface
public interface Printer<T> { String print(T object, Locale locale); } public interface Parser<T> { T parse(String text, Locale locale) throws ParseException; } public interface Formatter<T> extends Printer<T>, Parser<T> { }
package hello.typeconverter.formatter; import lombok.extern.slf4j.Slf4j; import org.springframework.format.Formatter; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; @Slf4j public class MyNumberFormatter implements Formatter<Number> { @Override public Number parse(String text, Locale locale) throws ParseException { log.info("text={}, locale={}", text, locale); NumberFormat format = NumberFormat.getInstance(locale); return format.parse(text); } @Override public String print(Number object, Locale locale) { log.info("object={}, locale={}", object, locale); return NumberFormat.getInstance(locale).format(object); } }
Formatter를 지원하는 Conversion Service
DefaultFormattingConversionService
: ConversionService를 상속받기 때문에 컨버터, 포매터 모두 등록 가능하다.
WebConfig 등록
package hello.typeconverter; import hello.typeconverter.converter.IntegerToStringConverter; import hello.typeconverter.converter.IpPortToStringConverter; import hello.typeconverter.converter.StringToIntegerConverter; import hello.typeconverter.converter.StringToIpPortConverter; import hello.typeconverter.formatter.MyNumberFormatter; import org.springframework.context.annotation.Configuration; import org.springframework.format.FormatterRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addConverter(new StringToIpPortConverter()); registry.addConverter(new IpPortToStringConverter()); registry.addFormatter(new MyNumberFormatter()); } }
스프링 기본 포매터
@Data static class Form { @NumberFormat(pattern = "###,###") private Integer number; @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime localDateTime; }
애노테이션을 이용해 포맷을 지정할 수 있다.
'Java > SpringBoot' 카테고리의 다른 글
API 예외 처리 (0) 2022.08.18 파일 업로드 (0) 2022.08.18 예외 처리와 오류 페이지 (0) 2022.08.18 의존성 주입 Dependency Injection. DI (0) 2021.02.24 [Thymeleaf] 문법 정리 (0) 2021.01.18