컨버터
새로운 타입을 만들어 변환하고 싶을 때, 컨버터를 만들어 등록하면 쉽게 사용할 수 있다.
컨버터 인터페이스
public interface Converter<S, T> {
T convert(S source);
}
S
타입에서 T
타입으로 변환하는 것이다.
> 참고 <
org.springframework.core.convert.converter
를 사용해야 한다.
사용 예시
@Getter
@EqualsAndHashCode
public class IpPort {
private String ip;
private int port;
public IpPort(String ip, int port) {
this.ip = ip;
this.port = port;
}
}
public class IpPortToStringConverter implements Converter<IpPort, String> {
@Override
public String convert(IpPort source) {
return source.getIp() + ":" + source.getPort();
}
}
public class StringToIpPortConverter implements Converter<String, IpPort> {
@Override
public IpPort convert(String source) {
// "127.0.0.1:8080"
String[] split = source.split(":");
String ip = split[0];
int port = Integer.parseInt(split[1]);
return new IpPort(ip, port);
}
}
IpPort 객체를 String 으로 변환하는 컨버터와,
String 을 IpPort 객체로 변환하는 컨버터이다.
컨버전 서비스
ConversionService 는 개별 컨버터를 묶어서 편리하게 사용할 수 있는 기능을 제공한다.
DefaultConversionService
ConversionService
: 컨버터 사용
ConversionRegistry
: 컨버터 등록
두 인터페이스를 구현하였다.
사용 방법
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new StringToIpPortConverter());
conversionService.addConverter(new IpPortToStringConverter());
assertThat(conversionService.convert("127.0.0.1:8080", IpPort.class))
.isEqualTo(new IpPort("127.0.0.1", 8080));
assertThat(conversionService.convert(new IpPort("127.0.0.1", 8080), String.class))
.isEqualTo("127.0.0.1:8080");
컨버터 등록 시에는 타입 컨버터를 명확히 알아야 하지만,
컨버터 사용 시에는 타입 컨버터를 모른 채로 convert()
를 사용하면 된다.
WebMvcConfigurer
스프링은 내부에서 ConversionService 를 제공한다.
WebMvcConfigurer 가 제공하는 addFormatters()
를 사용해서 추가하고 싶은 컨버터를 등록하면,
스프링이 ConversionService 에 컨버터를 추가해 준다.
포맷터
객체를 특정 포맷에 맞추어 문자로 출력할 때(또는 그 반대) 특화된 기능이 포맷터이다.
포맷터 인터페이스
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> {
}
print()
: 객체를 문자로 변경
parse()
: 문자를 객체로 변경
사용 예시
public class MyNumberFormatter implements Formatter<Number> {
@Override
public Number parse(String text, Locale locale) throws ParseException {
NumberFormat format = NumberFormat.getInstance(locale);
return format.parse(text);
}
@Override
public String print(Number object, Locale locale) {
return NumberFormat.getInstance(locale).format(object);
}
}
NumberFormat
은 숫자 중간에 가독성을 위한 쉼표를 적용해 주는 포맷터로 자바가 기본으로 제공하는 객체이다.
여기서 Locale
정보를 통해 나라별로 다른 숫자 포맷을 만들어 준다.
> 참고 <
Number 타입은 Integer, Long 같은 숫자 타입의 부모 클래스이다.
포맷터 지원 컨버전 서비스
내부에서 어댑터 패턴을 사용하여 포맷터도 컨버터처럼 동작하도록 지원한다.
DefaultFormattingConversionService
FormattingConversionService
: 포맷터를 지원하는 컨버전 서비스 (ConversionService 관련 기능 상속받음)
+ 기본적인 통화, 숫자 관련 기본 포맷터를 추가하여 제공
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new StringToIpPortConverter());
conversionService.addConverter(new IpPortToStringConverter());
conversionService.addFormatter(new MyNumberFormatter());
assertThat(conversionService.convert("127.0.0.1:8080", IpPort.class))
.isEqualTo(new IpPort("127.0.0.1", 8080));
assertThat(conversionService.convert(1000, String.class)).isEqualTo("1,000");
assertThat(conversionService.convert("1,000", Long.class)).isEqualTo(1000L);
WebConversionService
스프링 부트는 내부에서 DefaultFormattingConversionService 를 상속받은 WebConversionService 를 사용한다.
스프링 제공 기본 포맷터
스프링은 애노테이션 기반으로 원하는 형식을 지정해서 사용할 수 있는 포맷터를 제공한다.
@NumberFormat
: 숫자 관련 형식 포맷터 사용 (NumberFormatAnnotationFormatterFactory 사용됨)
@DataTimeFormat
: 날짜 관련 형식 지정 포맷터 사용 (Jsr310DateTimeFormatAnnotationFormatterFactory 사용됨)
@Data
class Form {
@NumberFormat(pattern = "###,###")
private Integer number;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime localDateTime;
}
타임리프 사용
*{{...}}
: 컨버전 서비스를 적용하여 변환된 결과로 조회
th:field="${...}"
: value 속성이 컨버젼 서비스를 적용하여 변환된 값을 갖는다.
> 참고 <
HttpMessageConverter 는
HTTP 메시지 바디 내용을 객체로 변환하거나 객체를 HTTP 메시지 바디에 입력하는 것이기 때문에
컨버전 서비스가 적용되지 않는다.
컨버전 서비스 @RequestParam
, @ModelAttribute
, @PathVariable
, 뷰 템플릿
등
메시지 컨버터 @RequestBody
, @ResponseBody
, HttpEntity
, ResponseEntity
등
출처 | 스프링 MVC 2(김영한) - 인프런
'💠프로그래밍 언어 > Java' 카테고리의 다른 글
[Spring] 서블릿 파일 업로드와 스프링 파일 업로드 (0) | 2025.04.06 |
---|---|
[Spring] API 에러 처리하는 방법, ExceptionResolver 와 @ControllerAdvice (0) | 2025.04.06 |
[Spring] 서블릿 예외 처리와 스프링 부트 예외 처리 (0) | 2025.04.04 |
[Spring] 컨트롤러 공통 작업 자동화 (ArgumentResolver 의 활용) (0) | 2025.04.04 |
[Spring] 인터셉터란? + 요청 로그 인터셉터, 인증 체크 인터셉터 예시 (0) | 2025.04.04 |