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;
}
애노테이션을 이용해 포맷을 지정할 수 있다.
반응형