- 사용자 입력을 자바 객체로 바인딩하는 기술
- 키는 JavaBean 스타일의 프로퍼티 경로를 따라야 함
1. DataBinder (org.springframework.validation)
- 요청 파라미터를 요청이 담긴 객체에 바인딩하고 검증까지 수행하는 도우미 클래스
| 기능 | 설명 | 비고 |
| 데이터 바인딩 | Map<String, String[]> 형식의 요청 파라미터를 대상 객체의 필드에 바인딩 |
타입 변환기를 통해 변환
(문자열 → 숫자, 날짜, enum 등) |
| 유효성 검증 | 등록된 Validator를 이용해 바인딩된 객체 상태를 검사 |
binder.validate() 호출
(결과는 BindingResult에 저장) |
| 에러 결과 관리 | 바인딩/검증 오류 시 FieldError, ObjectError 객체 생성 |
BindingResult 안에 담김
(에러 코드도 함께 포함됨) |
| 메시지 매핑 | 에러 코드 → MessageCodesResolver를 통해 여러 메시지 코드로 확장 |
MessageSource에서 가장 구체적인 메시지를 우선적으로 조회
|
| 컨트롤러 활용 | 컨트롤러 메서드에서 BindingResult를 받아 에러 메시지 처리 가능 |
- @InitBinder로 Validator 등록
- 수동으로 DataBinder 사용 |
2. 바인딩 방식
| 항목 | Constructor Binding |
Property Binding
|
| 바인딩 대상 | 생성자 파라미터 | setter |
| 내부 메커니즘 | 생성자를 통해 객체 생성 |
BeanWrapper로 필드 세팅
|
| 생성자 조건 | 단일 생성자만 존재해야 함 | 필요 없음 |
| 파라미터 매핑 방식 | 파라미터 이름 기준 (@ConstructorProperties 사용 가능) |
프로퍼티 이름과 setter로 자동 매핑
|
| 중첩 객체 자동 생성 | ✅ | ✅ |
| 컬렉션 지원 | ✅ | ✅ |
| 사용 예 | record, DTO, 불변 객체 |
일반적인 JavaBean, mutable 객체
|
예제) Constructor Binding
더보기
public class Account {
private final String name;
private final int age;
@ConstructorProperties({"name", "age"}) // 필드의 key 지정
public Account(String name, int age) {
this.name = name;
this.age = age;
}
// getter만 존재 (setter 없음)
public String getName() { return name; }
public int getAge() { return age; }
}
DataBinder binder = new DataBinder(null); // target 없이 초기화
binder.setTargetType(Account.class); // 대상 타입 설정
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("name", "노아");
pvs.add("age", "29");
Account account = (Account) binder.construct(pvs).getTarget();
System.out.println(account.getName()); // 노아
System.out.println(account.getAge()); // 29
예제) Property Binding
더보기
public class Account {
private String name;
private int age;
public void setName(String name) { this.name = name; }
public void setAge(int age) { this.age = age; }
public String getName() { return name; }
public int getAge() { return age; }
}
Account account = new Account(); // 미리 객체 생성
DataBinder binder = new DataBinder(account);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("name", "노아");
pvs.add("age", "29");
binder.bind(pvs);
System.out.println(account.getName()); // 노아
System.out.println(account.getAge()); // 29
3. BeanWrapper
- JavaBean 객체의 매핑을 지원하는 도구 (프로퍼티의 읽기/쓰기, 중첩 접근, 인덱스 접근 등)
예제
더보기
BeanWrapper company = new BeanWrapperImpl(new Company());
company.setPropertyValue("name", "Some Company Inc.");
company.setPropertyValue("managingDirector.name", "Jim Stravinsky");
Float salary = (Float) company.getPropertyValue("managingDirector.salary");
4. PropertyEditor
- String ↔️ Object 변환기
| 클래스명 | 설명 |
| ByteArrayPropertyEditor | 문자열 → 바이트 배열 |
| ClassEditor | 문자열 → Class 객체 |
| CustomBooleanEditor | 문자열 → Boolean |
| CustomDateEditor | 문자열 → Date (사용자 정의 포맷 필요) |
| CustomNumberEditor | 문자열 → 숫자 (Integer, Float 등) |
| LocaleEditor | 문자열 → Locale |
| StringTrimmerEditor | 문자열 공백 제거 및 빈 문자열을 null로 변환 |
Customize
- PropertyEditorSupport 클래스를 상속
- setAsText(String text) 메서드를 오버라이드
- CustomEditorConfigurer 또는 WebDataBinder를 통해 등록
예제
더보기
public class PhoneNumber {
private String areaCode;
private String number;
public PhoneNumber(String areaCode, String number) {
this.areaCode = areaCode;
this.number = number;
}
public String getAreaCode() { return areaCode; }
public String getNumber() { return number; }
@Override
public String toString() {
return areaCode + "-" + number;
}
}
public class PhoneNumberEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text == null || !text.contains("-")) {
throw new IllegalArgumentException("전화번호 형식이 잘못됨");
}
String[] parts = text.split("-");
if (parts.length != 2) {
throw new IllegalArgumentException("올바른 전화번호 형식이 아님");
}
PhoneNumber phoneNumber = new PhoneNumber(parts[0], parts[1]);
setValue(phoneNumber);
}
}
class User {
private PhoneNumber phone;
public PhoneNumber getPhone() { return phone; }
public void setPhone(PhoneNumber phone) { this.phone = phone; }
}
User user = new User();
DataBinder binder = new DataBinder(user);
// 📌 커스텀 PropertyEditor 등록
binder.registerCustomEditor(PhoneNumber.class, new PhoneNumberEditor());
// 📌 폼 파라미터처럼 전달된 값
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("phone", "010-1234");
binder.bind(pvs);
System.out.println(user.getPhone()); // 010-1234
출처
'Spring > Spring' 카테고리의 다른 글
| [Spring][Validation] 2. Java Bean Validation (0) | 2025.04.06 |
|---|---|
| [Spring][Validation] 1. Validator (0) | 2025.04.06 |
| [Spring][Field] 2. Formatting (0) | 2025.04.06 |
| [Spring][Field] 1. Type Conversion (0) | 2025.04.06 |
| [Spring][Core] 3-5. Container: Additional Capabilities of the ApplicationContext (0) | 2025.04.06 |