[스프링과 스프링 MVC] 4. LocalDate 바인딩이 왜 자주 깨지는가

2026. 3. 31. 00:09·Web/Web Basics

Formatter로 “문자열 → 타입” 변환 규칙을 등록한다

스프링 MVC의 파라미터 바인딩은 편하다.

  • 요청 파라미터가 문자열로 들어와도
  • int/boolean 같은 기본 타입은 자동 변환해주고
  • DTO 필드에도 알아서 채워준다

그런데 실전에서 가장 자주 터지는 타입이 있다.

  • 날짜(LocalDate, LocalDateTime)

 

1) 왜 날짜에서 에러가 자주 나나

HTTP 요청 파라미터는 기본적으로 전부 문자열이다.

예를 들어 사용자가 폼에서 날짜를 입력하면 이런 문자열이 온다.

  • dueDate=2020-10-10

문제는 스프링이 이 문자열을

  • LocalDate 객체로 바꾸는 규칙을 “항상 자동으로 알 수는 없다”는 점이다.

즉 바인딩 과정에서

  • “String을 LocalDate로 변환할 수 없다”
  • 같은 타입 변환 에러가 발생할 수 있다.
// ================================
// [문제 상황] 스프링 MVC가 "문자열"을 LocalDate로 자동 변환 못 해서 에러가 나는 케이스
// - 요청: dueDate=2020-10-10
// - DTO: LocalDate dueDate
// ================================

@Data
public class TodoDTO {
    private String title;
    private LocalDate dueDate; // ✅ 여기서 바인딩 문제가 자주 난다
}

 

2) 해결 방법 1: @DateTimeFormat

DTO 필드에 날짜 형식을 명시하면 된다.

@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate dueDate;

이렇게 하면 스프링이

  • yyyy-MM-dd 패턴으로 문자열을 파싱해서 LocalDate로 변환한다.

즉 특정 필드/파라미터에 대해 “형식”을 선언하는 방식이다.

 

3) 해결 방법 2: Formatter 등록 (전역 규칙을 만드는 방식)

`@DateTimeFormat`은 간단하지만
프로젝트 전체에서 동일한 규칙을 강제하거나, 커스텀 규칙이 더 필요하면 Formatter를 쓴다.

Formatter는 한 문장으로 말하면 이거다.

문자열 ↔ 특정 타입 변환 규칙을 코드로 등록하는 장치

 

Formatter는 두 메서드를 가진다.

  • parse(String text, Locale locale) : 문자열 → 타입
  • print(T object, Locale locale) : 타입 → 문자열

LocalDateFormatter는 이런 식이다.

  • 2020-10-10 → LocalDate.of(2020,10,10)

 

4) Formatter는 어디에 등록하나

스프링 MVC에서는 보통 `WebMvcConfigurer`에서 등록한다.

@Override
public void addFormatters(FormatterRegistry registry) {
    registry.addFormatter(new LocalDateFormatter());
}

이렇게 등록하면

  • 프로젝트 전체에서 LocalDate 바인딩에 이 규칙이 적용될 수 있다.

즉 “전역 타입 변환 규칙”을 등록하는 방식이다.

 

5) 언제 무엇을 쓰는가

  • 빠르게 해결: @DateTimeFormat
  • 프로젝트 전체 규칙/커스텀 변환 필요: Formatter 등록

둘 다 결국 같은 문제를 해결한다.

  • “문자열로 들어온 요청 데이터를, 원하는 타입으로 변환하는 규칙”을 제공한다

 

핵심 정리

  • HTTP 요청 파라미터는 기본적으로 문자열이다
  • LocalDate 같은 타입은 문자열 → 타입 변환 규칙이 필요해서 바인딩 에러가 자주 난다
  • @DateTimeFormat은 필드 단위로 형식을 지정하는 쉬운 해결책이다
  • Formatter는 문자열 ↔ 타입 변환 규칙을 전역으로 등록하는 방식이다
  • Formatter는 WebMvcConfigurer의 addFormatters로 등록한다

 

'Web > Web Basics' 카테고리의 다른 글

[스프링과 스프링 MVC] 3. 파라미터 바인딩과 Model  (0) 2026.03.30
[스프링과 스프링 MVC] 2. 스프링 MVC는 “프론트 컨트롤러”로 움직인다  (0) 2026.03.30
[스프링과 스프링 MVC] 1. DI와 빈(Bean)  (0) 2026.03.30
[상태 유지와 공통 처리] 5. MyBatis 설정 흐름  (0) 2026.03.30
[상태 유지와 공통 처리] 4. MyBatis는 무엇을 해결하는가  (0) 2026.03.30
'Web/Web Basics' 카테고리의 다른 글
  • [스프링과 스프링 MVC] 3. 파라미터 바인딩과 Model
  • [스프링과 스프링 MVC] 2. 스프링 MVC는 “프론트 컨트롤러”로 움직인다
  • [스프링과 스프링 MVC] 1. DI와 빈(Bean)
  • [상태 유지와 공통 처리] 5. MyBatis 설정 흐름
sqaxe1
sqaxe1
woojoo-devlog 님의 블로그 입니다.
  • sqaxe1
    Woojoo's Devlog
    sqaxe1
  • 전체
    오늘
    어제
    • 분류 전체보기 (148)
      • Backend (9)
        • Servlet (7)
        • Spring (2)
      • Frontend (1)
      • CS (0)
      • Book (33)
        • 자바 웹 프로그래밍 Next Step (30)
        • 테스트 주도 개발: 고품질 쾌속개발을 위한 TDD.. (1)
        • 성공과 실패를 결정하는 1%의 네트워크 원리 (2)
      • Engineering (0)
        • Testing (0)
      • Infra (6)
        • AWS (6)
      • Java (4)
      • Network (1)
      • 김영한 (28)
        • 자바 입문 (8)
        • 실전 자바 - 기본편 (6)
        • 실전 자바 - 중급편 (10)
        • 실전 자바 - 고급편 (4)
      • Web (39)
        • Web Basics (39)
      • Project (24)
        • NeoSquare (0)
        • Memo Evolution (24)
      • 정보처리기사 (0)
  • 블로그 메뉴

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

  • 공지사항

  • 인기 글

  • 태그

    java
    aws
    개발서적
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
sqaxe1
[스프링과 스프링 MVC] 4. LocalDate 바인딩이 왜 자주 깨지는가
상단으로

티스토리툴바