[Spring]Converter 보다 세부적으로 타입변경하는 법

2025. 4. 16. 20:54·Spring

✅ Formatter

♐ Formatter 이란?

  • 주로 사용자 지정 포맷을 적용해 데이터 변환을 처리할 때 사용된다. 
  • Formatter는 ConversionService와 비슷한 목적을 가지지만 문자열을 객체로 변환하거나 객체를 문자열로 변환하는 과정에서 포맷팅을 세밀하게 제어할 수 있다.

공식문서

https://docs.spring.io/spring-framework/reference/core/validation/format.html

 

Spring Field Formatting :: Spring Framework

As discussed in the previous section, core.convert is a general-purpose type conversion system. It provides a unified ConversionService API as well as a strongly typed Converter SPI for implementing conversion logic from one type to another. A Spring conta

docs.spring.io

 

♐ Formatter Interface

  • Printer, Parser 상속
  • 객체를 문자로 변환하고 문자를 객체로 변환하는 두가지 기능을 모두 가지고 있다.

1️⃣ Printer

  • Object를 String으로 변환한다.

2️⃣ Parser

  • String을 Object로 변환한다.

 

✅ 실습 

  • 숫자(10000)를 금액 형태(10,000)로 변환하는 Formatter 방법
@Slf4j
public class PriceFormatter implements Formatter<Number> {
	
	@Override
  public Number parse(String text, Locale locale) throws ParseException {
    log.info("text = {}, locale={}", text, locale);
		
		// 변환 로직
		// NumberFormat이 제공하는 기능
		NumberFormat format = NumberFormat.getInstance(locale);
		// "10,000" -> 10000L
		return format.parse(text);
  }

  @Override
  public String print(Number object, Locale locale) {
			log.info("object = {}, locale = {}", object, locale);
			// 10000L -> "10,000"
      return NumberFormat.getInstance(locale).format(object);
  }
	
}

 

테스트 코드

class PriceFormatterTest {

		PriceFormatter formatter = new PriceFormatter();

    @Test
    void parse() throws ParseException {
        // given, when
        Number result = formatter.parse("1,000", Locale.KOREA);

        // then
        // parse 결과는 Long
        Assertions.assertThat(result).isEqualTo(1000L);
    }

    @Test
    void print() {
        // given, when
        String result = formatter.print(1000, Locale.KOREA);

        // then
        Assertions.assertThat(result).isEqualTo("1,000");
    }
}

 

결과

 

 

✅ Spring에 활용되는 Formatter

♐FormattingConversionService

  • ConversionService와 Formatter를 결합한 구현체
  • 타입 변환과 포맷팅이 필요한 모든 작업을 한 곳에서 수행할 수 있도록 설계되어 있어서 다양한 타입의 변환과 포맷팅을 쉽게 적용할 수 있다.

♐DefaultFormattingConversionService

  • FormattingConversionService + 통화, 숫자관련 Formatter를 추가한것

 

사용 예시

public class FormattingConversionServiceTest {

    @Test
    void formattingConversionService() {

        // given
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();

        // Converter 등록
        conversionService.addConverter(new StringToPersonConverter());
        conversionService.addConverter(new PersonToStringConverter());
        // Formatter 등록
        conversionService.addFormatter(new PriceFormatter());

        // when
        String result = conversionService.convert(10000, String.class);

        // then
        Assertions.assertThat(result).isEqualTo("10,000");

    }

}

 

 

✅ Spring에 활용되는 Format Annotation

♐@ NumberFormat ,@DateFormat

  • 숫자 관련 지정 Formatter 사용
  • 날짜 관련 지정 Formatter 사용
@Data
public class FormatForm {

    @NumberFormat(pattern = "#,###.##")
    private BigDecimal price;

    @DateTimeFormat(pattern = "dd-MM-yyyy")
    private LocalDate orderDate;
    
}
@RestController
public class FormatController {

    @PostMapping("/format")
    public ResponseEntity<String> format(@ModelAttribute FormatForm form) {
        return new ResponseEntity<>(
                "form.getPrice() = " + form.getPrice() +
                        " form.getOrderDate() = " + form.getOrderDate(),
                HttpStatus.OK
        );
    }
}

 

결과

 

  •  

♐ @JsonFormat

  • `@JsonFormat`은 날짜 형식이나 숫자 포맷을 지정할 수 있다.
  •  콤마를 포함한 숫자는 Jackson이 자동으로 변환하지 않으므로 커스텀 처리가 필요하다.
  • 커스텀 데이터의 변환이 필요한 경우 `Deserialize` 사용
@Data
public class JsonFormatDtoV2 {

    @JsonDeserialize(using = CurrencyDeserializer.class)
    private BigDecimal price;

    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy")
    private LocalDate orderDate;

}
@PostMapping("/json-format/annotation")
public ResponseEntity<String> jsonFormatAnnotation(@RequestBody JsonFormatDtoV2 dto) {
    return new ResponseEntity<>(
            "dto.getPrice() = " + dto.getPrice() +
                    " dto.getOrderDate() = " + dto.getOrderDate(),
            HttpStatus.OK
    );
}

 

 

공식문서

https://docs.spring.io/spring-framework/reference/core/validation/format.html#format-CustomFormatAnnotations

 

Spring Field Formatting :: Spring Framework

As discussed in the previous section, core.convert is a general-purpose type conversion system. It provides a unified ConversionService API as well as a strongly typed Converter SPI for implementing conversion logic from one type to another. A Spring conta

docs.spring.io

 

 

 

'Spring' 카테고리의 다른 글

[Spring]오프셋 페이징보다 커서 페이징을 써야하는 이유  (1) 2025.04.25
[Spring/JPQL] JPQL이 무엇인지 알고 사용하자  (1) 2025.04.18
[Spring]HttpMessageConverter  (0) 2025.04.16
[SPRING/JPA]양방향 관계시 사용하는 CASCADE에 대해 알아보자  (1) 2025.04.11
[Spring/JPA] 영속성 컨텍스트  (0) 2025.04.11
'Spring' 카테고리의 다른 글
  • [Spring]오프셋 페이징보다 커서 페이징을 써야하는 이유
  • [Spring/JPQL] JPQL이 무엇인지 알고 사용하자
  • [Spring]HttpMessageConverter
  • [SPRING/JPA]양방향 관계시 사용하는 CASCADE에 대해 알아보자
코딩로봇
코딩로봇
금융 IT 개발자
  • 코딩로봇
    쟈니의 일지
    코딩로봇
  • 전체
    오늘
    어제
    • 분류 전체보기 (133) N
      • JavaScript (8)
      • SQL (10)
      • 코딩테스트 (29)
        • Java (15)
        • SQL (12)
      • Java (10)
      • 프로젝트 (21) N
        • 트러블슈팅 (7) N
        • 프로젝트 회고 (12)
      • git,Github (2)
      • TIL (35) N
      • Spring (16)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    스파르타 코딩 #부트캠프 #첫ot
    java #arraylist #list #배열
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
코딩로봇
[Spring]Converter 보다 세부적으로 타입변경하는 법
상단으로

티스토리툴바