일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 자료구조
- 안드로이드스튜디오
- 혼공챌린지
- select
- 안드로이드
- Til
- 알고리즘
- CS
- 스터디
- 기술면접
- Android
- 티스토리챌린지
- MySQL
- 혼공파
- 코틀린
- 정처기
- SQL
- 코테
- 프로그래머스
- 인프런
- java
- 오블완
- 자바
- 정보처리기사
- 혼공단
- doitandroid
- groupby
- Kotlin
- join
- 카카오코테
- Today
- Total
Welcome! Everything is fine.
[Spring] Converter와 Fomatter 사용하기 본문
Converter 사용하기
Spring은 기본적인 컨버터를 제공하지만, 컨버터를 커스텀하게 구현할 수도 있다. 예를 들면, String 값을 특정 객체를 변환하고 싶다면 커스텀 컨버터를 구현해야 한다.
강의 실습을 따라 String 값을 Person 객체로 변환하는 컨버터를 구현해보자. Person 객체는 name과 age 필드를 갖는다. Controller에서 URL 파라미터를 Person 객체로 반환해야 한다면 커스텀 컨버터를 구현 후, WebMvcConfigurer 에서 등록해야 한다.
@GetMapping("/type-converter")
public void typeConverter(@RequestParam Person person) {
log.info("person.getName() = {}", person.getName());
log.info("person.getAge() = {}", person.getAge());
}
다음과 같이 Converter 인터페이스를 implements 한 StringToPersonConverter 클래스를 만든다. 그리고 convert() 메서드를 오버라이드 한다. convert() 메서드 내부에서는 "gom:1200" 과 같은 문자열이 들어오면 : 를 기준으로 나눈 후 이름과 나이를 구해 새로운 Person 객체를 반환하고 있다.
public class StringToPersonConverter implements Converter<String, Person> {
// source = "gom:1200"
@Override
public Person convert(String source) {
String[] parts = source.split(":");
String name = parts[0];
int months = Integer.parseInt(parts[1]);
int age = months / 12;
return new Person(name, age);
}
}
그 다음 WebMvcConfigurer 인터페이스를 implements 한 WebConfig 클래스를 만든다. WebConfig 클래스에 다음과 같이 커스텀 컨버터를 등록해야 한다. 오버라이드 한 addFormatters() 메서드 내부에 registry.addConverter()를 통해 등록하자.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToPersonConverter());
registry.addConverter(new PersonToStringConverter());
}
}
이제 실행 후 Postman에서 테스트해본다. 정상적으로 작동하는 것을 볼 수 있다.
인텔리제이에서도 다음과 같이 이름과 나이가 잘 변환되어 출력된다.
Fomatter 사용하기
Fomatter는 Converter 보다 더 세밀한 문자열 포맷팅을 할 수 있는 기능이다. Formatter 인터페이스를 implements 해서 날짜, 숫자 같은 특정 데이터 포맷으로 변환해보자.
다음과 같이 Formatter 인터페이스를 implements한 PriceFormatter 클래스를 만든다. 그리고 parse() 메서드와 print() 메서드를 오버라이드한다.
@Slf4j
public class PriceFormatter 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);
}
}
- Locale : 지역 및 언어 정보를 나타내는 객체. Locale 정보를 활용하여 나라별로 다른 숫자 포맷으로 만들어준다.
컨버터와 같이 WebConfig에 등록해준다.
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new PriceFormatter());
}
}
Postman에서 잘 실행되는 모습을 볼 수 있다.
인텔리제이에서도 잘....되나? 했는데 당연히 위에 적어놓은 Log가 찍힐 줄 알았는데 찍히지 않았다. 찾아보니 Spring이 내부적으로 StringToBigDecimalConverter과 같은 기본 변환기를 사용해 변환할 수 있기 때문에 PriceFormatter가 실행되지 않을 가능성이 있다고 한다.
그래서 addFormatterForFieldType()을 사용해 특정 타입에 대해 강제로 PriceFormatter를 사용하도록 설정하니 로그가 제대로 찍혔다. 하지만 기본 변환기로 변환이 되는거라면 굳이 강제로 사용하게 할 이유는 없는 것 같다..🤔 이 부분은 더 알아봐야겠다.
'TIL' 카테고리의 다른 글
[Spring] @EntityGraph로 N+1문제 해결하기 (0) | 2025.02.26 |
---|---|
[Spring] Spring에서 세션을 다루는 3가지 방법, 뭐가 제일 좋을까? (0) | 2025.02.22 |
[Git] 로컬 브랜치에서 pull 할 때 에러 발생 - stash로 임시 커밋하기 (0) | 2025.02.18 |
[Spring] 왜 엔티티에 Setter를 사용하면 안 될까? (0) | 2025.02.13 |
[Spring] INSERT 됐지만 테이블이 안 보이는 문제 - @Transactional (0) | 2025.02.12 |