Java/SpringBoot

타입 컨버터

Choi G.H 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;
 }

애노테이션을 이용해 포맷을 지정할 수 있다.

반응형