Date 를 원하는 형식을 변경

 

String birth 를 Data 타입으로 변경

 

User.java

package com.jcy.usedhunter;

import java.util.Date;

public class User {

	private String id;
	private String pwd;
	private String name;
	private String email;
	private Date birth;
	private String sns;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getPwd() {
		return pwd;
	}

	public void setPwd(String pwd) {
		this.pwd = pwd;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Date getBirth() {
		return birth;
	}

	public void setBirth(Date birth) {
		this.birth = birth;
	}

	public String getSns() {
		return sns;
	}

	public void setSns(String sns) {
		this.sns = sns;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", pwd=" + pwd + ", name=" + name + ", email=" + email + ", birth=" + birth + ", sns="
				+ sns + "]";
	}

}

 

 

 

RegisterController.java

 

save 메서드 파라미터에 BindingResult 추가

BindingResult 추가 시 주의 점은

바인딩할 객체 바로 뒤에 코드를 추가해 주어야 한다.

BindingResult 는 스프링이 제공하는 검증 오류를 보관하는 객체이기 때문에

데이터 유효성 검사를 실패하면 ConstranitViolationException 을 발생시키고

데이터가 유효하지 않은 속성이 있으면 에러 정보를 BindingResult 에 담는다.

정상적인 동작에서는 BindingResult 에 담은 오류 정보를 가지고 컨트롤러를 호출한다.

 

BindingResult 에 검증 오류를 적용하는 방법은 3가지가 있다.

1. @ModelAttribute 의 객체에 타입 오류 등으로 바인딩이 실패하는 경우 스프링이 FieldError 을 생성해서 BindingResult 에 넣어준다.

2. new FieldError 를 만들어서 직접 넣는다.

3. Vaildator 를 사용(@Valid, @Validated)

 

BindingResult 메서드 설명
boolean hasError() 에러의 유무를 판단한다.
boolean hasGlobalError() 글로벌 에러의 유무를 판단한다.
void addError(ObjectError error) field, type, value 등의 에러를 출력할 수 있다.
void rejectValue() field, errorCode, defaultMessage 등을 받아서 reject 되면 데이터를 남길수 있다.

 

BindingResult 파라미터 설명
objectName 오류가 발생한 객체의 이름
field 오류 필드
rejectedValue 사용자가 입력한 값(거절된 값)
bindingFaliure 타입 오류 같은 바인딩 실패인지, 검증 실패인지 구분 값
codes 메시지 코드
arguments 메시지에서 사용하는 인자
defaultMessage 기본 오류 메시지
package com.jcy.usedhunter;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class RegisterController {

//	@RequestMapping("/register/add")
//	@RequestMapping(value="/register/save", method= {RequestMethod.GET, RequestMethod.POST})
	@GetMapping("/register/add")
	public String register() {
		return "registerForm";
	}

//	@RequestMapping(value="/register/save", method=RequestMethod.POST)
	@PostMapping("/register/save") // Spring 4.3 부터 추가
	public String save(User user, BindingResult result, Model m) throws Exception {

		// 1. 유효성 검사
		if (!isValid(user)) {

			String msg = URLEncoder.encode("id를 잘못입력하셨습니다.", "utf-8");
			m.addAttribute("msg", msg);

//			return "redirect:/register/add?msg="+msg; // URL 재작성(rewriting)
			return "redirect:/register/add";
		}

		// 2. DB에 신규회원 정보를 저장
		return "registerInfo";
	}

	private boolean isValid(User user) {
		// TODO Auto-generated method stub
		return true;
	}
}

 을

 

 

 

회원가입 페이지에서 등록을 해보자

 

 

birth 값이 null 로 변환실패다

 

 

 

형식 지정

 

RegisterController 에 다음 코드 추가

SimpleDateFormat("yyyy-MM-dd") 형식으로 들어온 데이터를

Date 형식으로 출력한다

new CustomDateEditor 의 false 는 빈 공간 유무를 정하는 역할이다.

변환 실패 없이 잘 출력 되었다.

	@InitBinder
	public void toDate(WebDataBinder binder) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(df, false));
	}

 

 

String 배열을 구분자를 설정해서 입력받기

 

StringArrayPropertyEditor("#") 을 추가

	@InitBinder
	public void toDate(WebDataBinder binder) {
		SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd");
		binder.registerCustomEditor(Date.class, new CustomDateEditor(df, false));
		binder.registerCustomEditor(String[].class, new StringArrayPropertyEditor("#"));

	}

 

 

 

 

@DateTimeFormat 어노테이션 사용

 

@DateTimeFormat(pattern="yyyy-MM-dd") 추가

CustomDateEditor 주석 처리

	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birth;
@InitBinder
	public void toDate(WebDataBinder binder) {
//		SimpleDateFormat df = new SimpleDateFormat("yyyy-mm-dd");
//		binder.registerCustomEditor(Date.class,  new CustomDateEditor(df, false));
		binder.registerCustomEditor(String[].class, new StringArrayPropertyEditor("#"));

	}

 

 

PropertyEditor

 

양방향 타입 변환(String  -> 타입, 타입 -> String) 특정 타입이나 이름의 필드에 적용가능

 

디폴트 PropertyEditor - 스프링이 기본적으로 제공

커스텀 PropertyEditor - 사용자가 직접 구현. PropertyEditorSupport 를 상속하면 편리

 

모든 컨트롤러 내에서의 변환 - WebBindingInitializer 를 구현 후 등록

특정 컨트롤러 내에서의 변환 - 컨트롤러에 @InitBinder 가 붙은 메서드를 작성

 

 

 

 

Converter 와 ConversionService

 

package com.jcy.usedhunter;

import org.springframework.core.convert.converter.Converter;

public class StringToStringArrayConverter implements Converter<String, String[]>{

	@Override
	public String[] convert(String source) {
		return source.split("#"); // String -> String[] 
	}
	

}

단방향 타입 변환(타입A -> 타입B) PropertyEditor 의 단점을 개선(stateful -> stateless)

 

디폴트 PropertyEditor - 스프링이 기본적으로 제공

커스텀 PropertyEditor - 사용자가 직접 구현. PropertyEditorSupport 를 상속하면 편리

 

ConversionService - 타입 변환 서비스를 제공. 여러 Converter 를 등록 가능

 

WebDataBinder 에 DefaultFormattingConversionService 이 기본 등록

모든 컨트롤러 내에서의 변환 - WebBindingInitializer 를 구현 후 등록

특정 컨트롤러 내에서의 변환 - 컨트롤러에 @InitBinder 가 붙은 메서드를 작성

 

 

 

Formatter

 

 

양방향 타입 변환(String  -> 타입, 타입 -> String) 바인딩할 필드에 적용 - @NumberFormat, @DateTimeFormat

public interface Formatter<T> extends Printer<T>, Parse<T>{}
public interface Printer<T> {
 	String print(T object, Locale locale); // Object -> String
}
public interface Parse<T> {
 	T parse(String text, Locale locale) throws ParesException; // String -> Object
}

	@DateTimeFormat(pattern="yyyy-MM-dd")
	private Date birth;
    
    @NumberFormat(pattern="###,###")
	BigDecimal salary;

 

 

복사했습니다!