스프링은 중간에 데이터를 변환해준다.
public String controllerMethod(@RequestParam Integer data) {...}
Http 쿼리스트링으로 전달하는 문자형 데이터를 스프링이 중간에 타입을 변환해준다.
-> data를 Integer타입으로 받을 수 있음
@RequestParam
, @ModelAttribute
, @PathVariable
)@Value
로 Yml정보 읽기Converters
인터페이스 사용Converters
인터페이스를 구현해서 등록하면, 스프링에 추가적 타입변환을 할 수 있다.
org.springframework.core.convert.converter.Converters
@Getter
@AllArgsConstructor
@EqualsAndHashCode // 모든 필드를 사용해서 equals(), hashCode() 생성 => 모든 필드 값이 같으면 a.equals(b)결과가 참이 됨
public class ConverterResponseDto {
private String id;
private String name;
}
Converter
구현public class CustomConverter implements Converter<String, RequestDto> {
@Override
public ConverterResponseDto convert(String source){
...변환작업
return new ConverterResponseDto(id, name);
}
//또는 반대로
@Override
public String convert(ResponseDto source){
//...변환작업
return "";
}
}
하나하나 직접 타입변환에 사용하는것은 불편 -> 개별 컨버터 모아서 묶어사용하는 기능
확인 기능 + 컨버팅 기능
@RequestParam
, @ModelAttribute
, @PathVariable
, 뷰 템플릿에서 사용가능
주의 : HttpMessageConverter는 컨버전서비스 적용x!
객체 -> JSON 변환시 메시지컨버터를 사용. 메시지컨버터는 내부에서 Jackson과 같은 라이브러리를ㄹ 사용 -> JSON 결과는 해당 라이브러리가 제공하는 설정을 통해 포맷지정
Repsonse시 : Spring의 기본 JSON 컨버터는 Jackson이며, @JsonFormat은 LocalDate 혹은 LocalDateTime을 JSON으로 직렬화할때 포맷을 관리
즉,
@ModelAttribute의 경우 역직렬화/직렬화시 컨버전서비스에서 등록한것을 모두 사용가능하다. + 스프링 기본제공 @DateTimeFormat 등도 사용 가능
하지만, JSON으로 데이터를 받는 역직렬화는 @DateTimeFormat등과 @JsonFormat 으로, 직렬화는 @JsonFormat으로만 가능
DefaultConversionService conversionService = new DefaultConversionService();
conversionService.addConverter(new CustomConverter());
CustomConvertResponse response = conversionService.convert("값", CustomConvertResponse.class);
DefaultConversionService
는 구현체이다.
ConversionService
: 컨버터 사용에 초점ConverterRegistry
: 컨버터 등록에 초점-> 관심사의 분리 (ISP)
@Configuration
public class webConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new CustomConverter());
}
}
@GetMapping
public String convertTest(@RequestBody ConverterResponseDto dto){
...
}
@RequestParam은 RequestParamMethodArgumentResolver가 ConversionService를 사용해 타입 변환 ...
이처럼 mvc 요청 파라미터가 사용하는 ArgumentResolver의 ConversionService가 타입변환을 해준다.
Converter는 입출력타입에 제한이 없음 (범용타입 변환, 즉 객체<->객체)
-> 하지만 웹 애플리케이션은 객체를 문자로 변환하거나 그 반대가 대부분 (객체<->문자)
public class CustomFormatter implements Formatter<객체타입> {
@Override
public 객체타입 parse(String text, Locale locale) throws ParseException {
객체format.getInstance(locale);
}
@Override
public String print(객체타입 object, Locale locale) {
...
return 객체Format.getInstance(locale).format(object);
}
}
컨버전 서비스는 컨버터만 등록, 포맷터는 등록 불가능.
하지만, 포맷터도 객체<->문자로 변환하는 컨버터일 뿐임.
즉, 포맷터를 지원하는 컨버전서비스 사용 가능! 내부에서 어댑터패턴을 사용해 포맷터가 컨버터처럼 동작하도록 지원
FormattingConversionService
DefaultFormattingConversionService
FormattingConversionService
+ 기본적 통화/숫자관련 기본포맷터 추가제공
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new CustomFormatter());
}
}
숫자/날짜관련 포맷터
public class RequestDto {
@NumberFormat(pattern = "###,###")
private Integer number;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDateTime localDateTime;
}