스프링타입 컨버터

달래·2024년 1월 22일
0

Spring

목록 보기
1/7

스프링은 중간에 데이터를 변환해준다.

public String controllerMethod(@RequestParam Integer data) {...}

Http 쿼리스트링으로 전달하는 문자형 데이터를 스프링이 중간에 타입을 변환해준다.
-> data를 Integer타입으로 받을 수 있음

스프링 기본 타입변환?

  • mvc 요청 파라미터 (@RequestParam, @ModelAttribute, @PathVariable)
  • @Value로 Yml정보 읽기
  • xml에 넣은 스프링 빈 정보 변환
  • 뷰 렌더링

타입변환을 새로 만들어 지정해주고싶다면? 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 "";
    }
}

그 외에도...다양한 타입컨버터 제공

  • Converter : 기본타입 컨버터
  • ConverterFactory : 전체클래스 계층구조 필요
  • GenericConverter : 정교구현, 대상필드 어노테이션 정보 사용가능
  • ConditionalGenericConverter : 특정조건 참인경우만 실행

ConversionService 컨버전서비스 인터페이스

하나하나 직접 타입변환에 사용하는것은 불편 -> 개별 컨버터 모아서 묶어사용하는 기능

  • 확인 기능 + 컨버팅 기능

  • @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)

  • 컨버터 사용 클라이언트와 컨버터 등록/관리 클라이언트의 관심사를 분리

실제 등록 : WebConfig

@Configuration
public class webConfig implements WebMvcConfigurer {
	@Override
    public void addFormatters(FormatterRegistry registry) {
    	registry.addConverter(new CustomConverter());
    }
}

Controller 사용

@GetMapping
public String convertTest(@RequestBody ConverterResponseDto dto){
	...
}

@RequestParam은 RequestParamMethodArgumentResolver가 ConversionService를 사용해 타입 변환 ...
이처럼 mvc 요청 파라미터가 사용하는 ArgumentResolver의 ConversionService가 타입변환을 해준다.


Formatter 포맷터 인터페이스

Converter는 입출력타입에 제한이 없음 (범용타입 변환, 즉 객체<->객체)
-> 하지만 웹 애플리케이션은 객체를 문자로 변환하거나 그 반대가 대부분 (객체<->문자)

  • Formatter는 문자에 특화되어있음 + 현지화(Locale: 날짜숫자는 현지화정보사용) -> 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 + 기본적 통화/숫자관련 기본포맷터 추가제공

WebConfig 등록

@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;
}

결론

  • 컨버저를 사용하든 포맷터를 사용하든, 사용할 때는 컨버전 서비스를 통해 일관성 있게 사용!
profile
아좌잣~!

0개의 댓글