1.WebDataBinder์ ์๋ฆฌ (๋ณต์ต)
(0)Binding์ด๋?
์์ฒญ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ปจํธ๋กค๋ฌ ๋งค์๋์ ์ธ์์ ์ฐ๊ฒฐ ์ํค๋ ๊ฒ์ ๋งํ๋ค.
WebDataBinder๋ ์์ฒญ์ ํ๋ผ๋ฏธํฐ๋ฅผ Controller Method์ ์ธ์์ ๋ง๊ฒ ํ๋ณํ์ ์์ผ์ฃผ๊ณ , ๋ ์ธ์๋ก ๋ค์ด๊ฐ ์ ์๋ ๊ฐ์ธ์ง ํ์ธํ๋ ์ฅ์น์ด๋ค. ํด๋น ๊ณผ์ ์ ๊ฑฐ์ณ์ ํ๋ผ๋ฏธํฐ๊ฐ ์ธ์์ ์ฐ๊ฒฐ๋๋ค.
(1) ํ ๋ณํ
์์ฒญ์ ํ๋ผ๋ฏธํฐ๋ ๋ฌด์กฐ๊ฑด String์ด๊ธฐ ๋๋ฌธ์ ํ ๋ณํ์ด ํ์ํ๋ค. ์ฌ๊ธฐ์๋ MyDate๋ผ๋ ๊ฐ์ฒด๊ฐ ์ปจํธ๋กค๋ฌ์ ์ธ์๋ก ์ฐ์๊ณ , ๊ฐ์ฒด์ ์ธ์คํด์ค ๋ณ์๋ก binding ๋์ด์ผ ํ๋ค. (binding ๋ ๋์์ Spring์ด ์์์ ์ก์์ค๋ค.) ๋ฐ๋ผ์ "2021"์ int 2021๋ก ๋ฐ๊ฟ์ฃผ๋ ์ญํ ์ ํ๋ค. ๋ง์ฝ ์ด ๊ณผ์ ์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด, (year = "Happy"๋ฅผ ๋ฃ์ด์ ๋ณํ ์คํจ ๋ฑ) ์๋ฌ์ ๋ํ ์ ๋ณด๋ฅผ BindingResult์ ๋ฃ๋๋ค.
(2)๋ฐ์ดํฐ ๊ฒ์ฆ
๋ฐ์ดํฐ ๊ฒ์ฆ์ ํด๋น ๋ณ์์ ๊ฐ์ผ๋ก ๋ค์ด๊ฐ๊ธฐ์ ๋ง์ด ๋๋๊ฐ?๋ฅผ ์ฒดํฌํ๋ ํํธ์ด๋ค. month์๋ 1~12๊น์ง์ ๊ฐ๋ง ๋ค์ด๊ฐ ์ ์๋ค. ๊ทผ๋ฐ ๋ง์ฝ์ month์ "31"์ด ๋ค์ด๊ฐ ์๋ค๋ฉด WebDataBinder๋ ๋ฐ์ดํฐ ๊ฒ์ฆ ๊ณผ์ ์์ ๋์จ ์๋ฌ์ ์ ๋ณด๋ฅผ BindingResult์ ๊ธฐ๋กํ ๊ฒ์ด๋ค. ๋ง์ฝ ์๋ฌ ์์ผ๋ฉด ๊ทธ๋๋ก Binding(์์ฒญ์ ํ๋ผ๋ฏธํฐ๋ ์ธ์์ ๋ค์ด๊ฐ ์ ์๊ฒ๋์ด ์ฌ์ฉ๋๋ค.)
Spring์ด WDB๋ฅผ ํตํด ํ ๋ณํ๊ณผ ๋ฐ์ดํฐ ๊ฒ์ฆ์ ๊ธฐ๋ณธ์ผ๋ก ํด์ฃผ์ง๋ง, ๋ด์ฅ๋ ๊ธฐ๋ฅ์ ๋ฒ์ด๋๋ ๋ฒ์ฃผ์ ์ผ์ฒ๋ฆฌ๋ ๋ชป ํ ์์๋ค. ์ฐ๋ฆฌ๊ฐ ์ด๋ฒ ํฌ์คํ ๊ณผ ๋ค์ ํฌ์คํ ์์ ๋ง๋ค ๊ฒ์ WebDataBinder๊ฐ ํ ๋ณํ์ด๋ ๋ฐ์ดํฐ ๊ฒ์ฆ์ ๋ชปํ๋ ๊ฒฝ์ฐ์, ์ฐ๋ฆฌ๊ฐ ์ง์ ํ ๋ณํ ๋งค์๋๋ ๋ฐ์ดํฐ ๊ฒ์ฆ ๋งค์๋๋ฅผ ๋ง๋ค์ด Binder์ ๋ฑ๋กํ์ฌ WebDataBinder๊ฐ ์๊ธฐ ์ญํ ์ ๋ค์ ์ ํด๋ผ ์ ์๊ฒ ํ๋ ๊ฒ์ด๋ค.
2.Register Controller์ ๋ณํ ๊ธฐ๋ฅ ์ถ๊ฐํ๊ธฐ - ์ค์ต
(0) insta,facebook,kakao ์ฒดํฌ ๋ฐ์ค์ ์ฒดํฌ ์น ๊ฒ์ด String์ผ๋ก ์ด๋ป๊ฒ ๋ณํ ๋์์๊น?
์๋ฅผ ๋ณด๋ฉด ์ฒดํฌ๋ฐ์ค์ ์ฐ์ ๊ฐ๋ค์ด String์ผ๋ก์ ๋ณํ ๋ ๊ฒ์ ์ ์ ์๋ค. Spring์ ์ฒ์์ ํด๋ผ์ด์ธํธ๊ฐ ์ฒดํฌํ ๊ฐ๋ค์ String ๋ฐฐ์ด๋ก์ ๋ฐ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๊ฑธ ๋ค์ ์ผ๋ ฌ๋ก ๋์ด๋ String์ผ๋ก ๋ณํํด์ฃผ๋ ๊ฒ์ด๋ค. ์ด๊ฑด Spring์ด ์๋์ผ๋ก ํด์ค๋ค.
(1) User ํด๋์ค์์ birth์ ์๋ฃํ์ String์ด ์๋ Date๋ก ๋ฐ๊พธ์ด๋ณด์.
(**Date ํด๋์ค๋ Java์์ ์ ๊ณตํ๋ ํด๋์ค๋ก ๋ ์์ผ ์๊ฐ์ ๋ฐํํ๋ค.)
//UserClass์์ ๋ณํ
public class User {
private String id;
private String pwd;
private String name;
private String email;
private Date birth;
private String[] sns;
private String[] hobby;
public String[] getHobby() {
return hobby;
}
public void setHobby(String[] hobby) {
this.hobby = hobby;
}
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
+ ", hobby="+ Arrays.toString(hobby) + "sns="+ Arrays.toString(sns) + "]";
}
}
๊ทธ๋ฆฌ๊ณ ์๋ฒ๋ฅผ ๋๋ ค๋ณด์. ํ์๊ฐ์ ์ฐฝ์ ์ด๊ฒ ๋ค.
๋ง์ฝ ์ด ํ์์ผ๋ก ์๋ ์์ผ์ ์ ์ผ๋ฉด ์ ๋๋ก ๋์๊ฐ๋ค. ์๋ํ๋ฉด yyyy/MM/dd ํ์์ Spring์ด Date ํด๋์ค์ ๋ณ์๋ก ๋ณํ ๊ฐ๋ฅํ ๋ณ์ฃผ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง ๋ค์๊ณผ ๊ฐ์ด ์ ์ผ๋ฉด ์๋ฌ๊ฐ ๋๋ค.
์ด์ ๋ yyyy-MM-dd ํ์์ Spring์ด ๋ณํํ ์ ์๋ ๊ธฐ๋ณธ ๋ฒ์ฃผ ๋ด์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ฐ๋ผ์ ์ด๋ฅผ ๋ณํํ๋ ๋งค์๋๋ฅผ ์ฐ๋ฆฌ๊ฐ ์ปค์คํฐ๋ง์ด์ง ํด์ ๋ง๋ค์ด์ค์ผ ํ๋ค.
(2) ์๋ฌ ๋๋๋ผ๋ ๋๊น์ง ์ถ๋ ฅํ๋ ๋ฐฉ๋ฒ์?
์ปจํธ๋กค๋ฌ์ ์ฐ๋ฆฌ๊ฐ binding ํ๋ ค๋ ๊ฐ์ฒด ์์ BindingResult ๊ฐ์ฒด๋ฅผ ์ธ์๋ก ๋ฃ๋๋ค.
public String save(User user,BindingResult result ,Model m) throws Exception {
//result ๊ฐ์ฒด๋ฅผ ์ฐ์ผ๋ฉด ์ด๋์ ์๋ฌ๊ฐ ๋ฌ๊ณ ์ด ๋ช๊ฐ์ ์๋ฌ๊ฐ ๋ฌ๋์ง ์๋ ค์ค๋ค.
System.out.println("result="+result);
if(!isValid(user)) {
String msg = URLEncoder.encode("id๋ฅผ ์๋ชป ์
๋ ฅํ์
จ์ต๋๋ค.", "utf-8");
m.addAttribute("msg",msg);
return "redirect:/register/add";
์ด๋ ๊ฒ ๋ฃ๊ณ ํ๋ก๊ทธ๋จ์ ๋๋ฆฌ๋ฉด, ๋ฐ์ธ๋ฉ ์คํจํ ๋ณ์์๋ Null ๊ฐ์ด ๋ค์ด๊ฐ ์ฑ๋ก ๊ฒฐ๊ณผ๊ฐ ์ ์ถ๋ ฅ๋๋ค.
์ ์ถ๋ ฅ๋๋ ์ด์ ๋ BindingResult๋ฅผ ์ปจํธ๋กค๋ฌ ๋งค์๋์ ์ธ์๋ก ๋ฃ๋ ๊ฒ์ ์๋ฏธ๋ ๋ค์๊ณผ ๊ฐ๋ค.
ํด๋น ๋งค์๋๊ฐ ์ผ ์ฒ๋ฆฌํ ๋, ๋ฐ์ธ๋ฉ ์ค๋ฅ๊ฐ ์๋๋ผ๋ ์๋ฌ ํ์ด์ง๋ก ๋์ด๊ฐ์ง ์๋๋ก ํ๋ ๊ฒ์ด๋ค.
๋ํ ๋ฐ์ธ๋ฉ ๊ฒฐ๊ณผ ์์ฒด๋ฅผ ์ปจํธ๋กค๋ฌํํ ์ฃผ๊ณ , ์ปจํธ๋กค๋ฌ๊ฐ ๋ฐ์ธ๋ฉ ์๋ฌ๋ฅผ ์ฒ๋ฆฌํ๋๋ก ๊ถํ์ ์ฃผ๋ ๊ฒ์ด๋ค.
(3) ๋ฌธ์์ด์ ๋ถ๋ถ ๋ถ๋ถ ์งค๋ผ์ Date์ ๋ณ์๋ก ๋ฃ์ด์ฃผ๋ ๋ณํ ๋งค์๋๋ฅผ ๋ง๋ค์.
์ด์ ์ฐ๋ฆฌ๋ yyyy-MM-dd ํจํด์ ๋ฌธ์์ด์ yyyy , MM, dd๋ก ์งค๋ผ์ Date์ ์ธ์คํด์ค ๋ณ์๋ก ๋ฃ์ด์ฃผ๋ ๋ณํ ๋งค์๋๋ฅผ ๋ง๋ค์ด๋ณด๊ฒ ๋ค. ๋จผ์ ์ฝ๋๋ฅผ ๋ณด์.
//Binder๋ก์ ํด๋น ๋งค์๋๋ฅผ ๋ฑ๋กํ๋ ์ด๋
ธํ
์ด์
@InitBinder
public void toDate(WebDataBinder binder) {
//๋
์์ผ SimpleDateFormat ๊ฐ์ฒด ์์ฑ
//ํด๋น ๊ฐ์ฒด๋ ๋ฌธ์๋ณ๋ก ๋ปํ๋ ์ซ์๊ฐ ๋ฌ๋ผ์ ์ด๊ฑธ ์ด์ฉํด ํจํด ๋ง๋ค ์ ์๋ค.
// y๊ฐ ๋ค์ด๊ฐ๋ฉด ๋
๋๋ฅผ ๋ํ๋ธ๋ค. M์ ์์ด๋ค. (1~12๋ง ๊ฐ๋ฅ), d๋ ๋ ์ง์ด๋ค.(1~31๋ง ๊ฐ๋ฅ)
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// binder์ ์๋ก์ด ์ปค์คํ
๋ฐ์ดํธ์๋ํฐ๋ก ๋ฑ๋กํ๋ค.
// ๋ฑ๋ก์ ์ฒซ๋ฒ์งธ ์ธ์๊ฐ ๋ฐ์ธ๋ฉํ ๊ฐ์ฒด์ ํด๋์ค์ ๋ณด, ์ปค์คํ
๋ฐ์ดํธ ์๋ํฐ ๊ฐ์ฒด ์์ฑ์ด๋ค.
// CustomDateEditor์ ์ธ์ ์ฒซ๋ฒ์งธ๋ ์ ๋ฐ์ธ๋ฉ ๋ฐฉ๋ฒ, ๋๋ฒ์งธ๋ ๊ณต๋ฐฑ ํ์ฉ ์ฌ๋ถ์ด๋ค.
binder.registerCustomEditor(Date.class, new CustomDateEditor(df,false));
}
(4) Register์ Hobby ์ถ๊ฐ (String์ผ๋ก ๋ฐ์ ๊ฒ์ String[]๋ก ์ง๋ฅด๊ณ ์ถ๋ค.)
resgisterForm๊ณผ User์ Hobby ์ถ๊ฐ
<!--registerForm.jsp ๋ด๋ถ-->
<label for="">์ทจ๋ฏธ</label>
<input class="input-field" type="text" name="hobby" placeholder="์ทจ๋ฏธ">
// User ๋ด๋ถ
private String[] hobby;
(5) String์ String []๋ก ๋ณํํ๋ ๋งค์๋ ์ถ๊ฐ
hobby๋ input ํ๋๋ก ๋ค์ด์ค๊ธฐ ๋๋ฌธ์ ๋ง์ฝ ๋ค์์ ์ทจ๋ฏธ๋ฅผ ์ ๋๋ค ํด๋, ๋ฐฐ์ด[0]์ ๋ค ๋ค์ด๊ฐ์, ๋ฌด์จ ์ทจ๋ฏธ ๊ฐ์ก๋์ง ์ ํธ๋ ์กฐ์ฌ ๊ฐ์ ๊ฒ์ ํ๊ธฐ ์ด๋ ค์ธ ๊ฒ์ด๋ค. ์ด๋ฅผ ๊ฐ๊ฐ ๋์ด๋ด์ String ๋ฐฐ์ด ๋ค๋ฅธ ์นธ์๋ ๋ค์ด๊ฐ๋๋ก ํด๋ณด์.
๋จผ์ ์ทจ๋ฏธ๋ค ์ฌ์ด์ #์ ๋ฃ์ด ์๋ก ๊ตฌ๋ถํ์ฌ ์ ๋ ฅํ๋ค๊ณ ๊ฐ์ ํ์. (์ด๋ ๊ฒ ์ ๋ ฅํ๋๋ก ํด๋ผ์ด์ธํธ ์ ๋)
๊ทธ๋ฌ๋ฉด ์ด๋ฒ์๋ #์ ๊ตฌ๋ถ์๋ก ํด์ String์ ๋ฐฐ์ด๋ก ๋์ด๋ด๋ ๋ณํ ๋งค์๋๋ฅผ ๋ง๋ค๋ฉด ๋๋ค. ์๊น ๋ง๋ ๋ณํ ๋งค์๋ ์์ ํด๋น ๋ณํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์.
// Binder๋ก์ ํด๋น ๋งค์๋๋ฅผ ๋ฑ๋กํ๋ ์ด๋
ธํ
์ด์
// ํด๋น ์ด๋
ธํ
์ด์
์ผ๋ก ๋ฑ๋ก๋ ๋ฐ์ธ๋๋ ํด๋น ์ปจํธ๋กค๋ฌ ๋ด๋ถ์์๋ง ์ ์ฉ์ด ๋๋ค.
@InitBinder
// ๋งค์๋์์ ๋ค์์ ๋ณํ ๊ธฐ๋ฅ์ ๋ฃ์ ์ ์๋ค.
public void toDate(WebDataBinder binder) {
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
binder.registerCustomEditor(Date.class, new CustomDateEditor(df,false));
//#์ ๊ธฐ์ค์ผ๋ก String์ ๋ฐฐ์ด๋ก ์งค๋ผ ๋ฃ๋ ๊ฐ์ฒด
binder.registerCustomEditor(String[].class, new StringArrayPropertyEditor("#"));
}
๋ง์ฝ ๊ฐ์ฒด ๋ด์ ์ด๋ค ํ๋์ ๋ํด์๋ง ํด๋น ๋ณํ ๊ธฐ๋ฅ์ด ๋์๊ฐ๋๋ก ํน์ ํ๊ณ ์ถ๋ค๋ฉด
binder.registerCustomEditor(String[].class, "hobby", new StringArrayPropertyEditor("#"));
์ด๋ ๊ฒ ์ ์ผ๋ฉด ๋๋ค.
์ด๋ฌ๋ฉด ๋ค๋ฅธ ์ ๋ ฅ๊ฐ๋ค์ ์๋ฌด๋ฆฌ ๋ง์ด ์ ์ด๋ ํ๋์ ๋ฌธ์์ด์ ๋ค ๋ฐ์ธ๋ฉ ๋๊ณ ,
hobby๋ ๋ณ์๋ง #์ ๊ธฐ์ค์ผ๋ก String ๋ฐฐ์ด๋ก ์งค๋ ค์ binding ๋๋ค.
(์ถ๊ฐ) Date ๋ณํ์ ๋น ๋ฅด๊ฒ ํ๋ ๋ฐฉ๋ฒ (์ด๊ฒ๋ฐ์ ๋ณํํ ๊ฒ ์์ด์ ๋ณํ ๋งค์๋ ๋ง๋ค๊ธฐ ๋ฒ๊ฑฐ๋ก์ด ๊ฒฝ์ฐ)
๊ทธ๋ฅ ๊ฐ์ฒด์ ์ธ์คํด์ค ๋ณ์ ์ ์ธ๋ถ๋ถ์ ์ด๋ ธํ ์ด์ ์ ์จ์ ๋ฐ๋ก ๋ณํํ ์๋ ์๋ค.
@DateTimeFormat(pattern="์ฐ๋ฆฌ๊ฐ ๋ฑ๋กํ ํจํด")
public class User {
private String id;
private String pwd;
private String name;
private String email;
//String์ ๋ ์ง, ๋ ์ง๋ฅผ String์ผ๋ก ์๋ฑกํฅ ๋ณํ ๊ฐ๋ฅํ ์ด๋
ธํ
์ด์
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date birth;
private String[] sns;
private String[] hobby;
/...
}
3. Spring์ ํ์ ๋ณํ ๊ธฐ๋ฅ๋ค ์ ๋ฆฌ (Property Editor, converter, Formatter)
(1) Property Editor
PropertyEditor๋ ์ข ๋ฅ๊ฐ ๋ง๋ค. ์ฐ๋ฆฌ๊ฐ ์ด StringArrayPropertyEditor๋ ๊ทธ ์ข ๋ฅ ์ค ํ๋์ด๋ค.
PropertyEditor ์ค์๋ ์คํ๋ง์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ ๋ํดํธPropertyEditor๊ฐ ์กด์ฌํ๋ค. ์ฐ๋ฆฌ๊ฐ ์ด String์ ์ ์ ํ ์งค๋ผ String[]์์ ์ง์ด๋ฃ๋ StringArrayPropertyEditor๋ ๊ทธ ์ค ํ๋์ด๋ค.
๋ํดํธ PropertyEditor์ ๋ชฉ๋ก์ ๋ค์๊ณผ ๊ฐ๋ค. ์ธ์ธ ํ์ ์๊ณ , ์ํฉ์ ๋ฐ๋ผ ์ ์ ํ ์ด์ฉํ์.
์ฌ์ฉ์๊ฐ ์ง์ ๊ตฌํํ ์๋ ์๋ค. ์ด๊ฑธ CustomPropertyEditor๋ผ๊ณ ํ๋ค. ๊ทผ๋ฐ ์๋ฌด๊ฒ๋ ์๋ ๊ฒ์์ ์ฒ์๋ถํฐ ๋ค ๊ตฌํํ๋ ๊ฒ์ ํ๋ค๋ค. ๊ทธ๋์ ๋ณดํต PropertyEditorSupport๋ฅผ ์์ํ์ฌ ์ด ๋ถ๋ชจํด๋์ค์ ๋งค์๋๋ฅผ ์ค๋ฒ๋ก๋ฉํ์ฌ ๋ง์ด ๊ตฌํํ๋ค.
PropertyEditor๋ ์๋ฐฉํฅ ํ์ ๋ณํ๊ธฐ์ด๋ค.
ํ๋์ Editor ๊ฐ์ฒด๊ฐ String์ A์๋ฃํ์ผ๋ก ๋ฐ๊ฟ ์ ์๊ณ , A ์๋ฃํ์ String์ผ๋ก ๋ฐ๊ฟ ์๋ ์๋ค.
๋ชจ๋ ์ปจํธ๋กค๋ฌ์์ ๊ตฌํํ PropertyEditor๊ฐ ์ ์ฉ๋์ด ๊ฐ์ด ๋ณํ ๋๋๋ก ํ๊ณ ์ถ๋ค๋ฉด, WebBindinfInitializer๋ผ๋ ๊ฒ์ ๊ตฌํ ํ ๋ฑ๋กํด์ผ ํ๋ค.
ํน์ ์ปจํธ๋กค๋ฌ ๋ด๋ถ์์๋ง ๊ตฌํํ PropertyEditor๊ฐ ์ ์ฉ๋๋๋ก ํ๊ณ ์ถ๋ค๋ฉด ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
๋จผ์ PropertyEditor๊ฐ์ฒด๊ฐ ํฌํจ๋ ๋ณํ ๋งค์๋๋ฅผ ์ปจํธ๋กค๋ฌ ๋ด๋ถ์ ์์ฑํ๊ณ ์ด ๋งค์๋์ @InitBinder ์ด๋ ธํ ์ด์ ์ ๋ถ์ธ๋ค.
(2) Converter
Converter๋ ๋จ๋ฐฉํฅ ๋ณํ๊ธฐ์ด๋ค. ํ๋์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋์ผ๋ฉด ์ด ๊ฐ์ฒด๋ String -> ๋ค๋ฅธ ํ์ ํน์ ๋ค๋ฅธ ํ์ -> String ํ ๋ฐฉํฅ์ผ๋ก ๋ฐ์ ๋ณํํ์ง ๋ชปํ๋ค. ๋ฐ๋ผ์ PropertyEditor์ ๊ฐ์ ์ฑ๋ฅ์ ๋ด๊ฒ ํ๊ณ ์ถ๋ค๋ฉด, Converter 2๊ฐ๋ฅผ ์จ์ผํ๋ค.
ํ์ ์์๋ Converter๋ฅผ ๋ง์ด ์ฌ์ฉํ๋ค. ๊ทธ ์ด์ ๋ Converter๋ PropertyEditor์ ๋ฌ๋ฆฌ iv(์ธ์คํด์ค ๋ณ์)๋ฅผ ์ฐ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค. PropertyEditor๋ ์ธ์คํด์ค ๋ณ์๋ฅผ ์ฐ๋๋ฐ, ์ด๋ ๋ง๋๋ ๊ฐ์ฒด๋ง๋ค ์์ ๋ณ์ ๊ฐ์ด ๋ฌ๋ผ์ง๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค. ์ด๋ฌ๋ฉด ์ฑ๊ธํค์ ์คํํ ์ ์๋ค. ๋ฐ๋ฉด ์ธ์คํด์ค ๋ณ์๊ฐ ์๋ Converter๋ ์ฑ๊ธํค์ ์คํํ ์ ์๋ค.
(์ฑ๊ธํค์ด๋, ๊ฐ์ ์์ฒญ ๋ง๋ค ์์ฒญ์ ์ฒ๋ฆฌํ ๊ฐ์ฒด๋ฅผ ์๋ก ๋ง๋ค์ง ์๊ณ , ๊ทธ ์์ฒญ์ ํด๊ฒฐํ ์ ์๋ ๊ฐ์ฒด๋ฅผ ํ๋ ๋ง๋ค๊ณ ๊ฐ์ ์์ฒญ์ด ๋ค์ด์ฌ ๋๋ง๋ค ๊ทธ ๊ฐ์ฒด๋ฅผ ์ฌ์ฌ์ฉ ํ๋ ๊ฒ์ด๋ค.)
Spring์ WebDataBinder์๋ DefaultFormattingConversionService๋ผ๋ Converter๋ค์ด ๊ธฐ๋ณธ์ผ๋ก ๋ฑ๋ก๋์ด ์๋ค.
ํ๋์ Converter๋ฅผ ์ด์ฉํ๋ ๋งค์๋๋ฅผ ๋ง๋ค๊ณ , ์ด ๋งค์๋๊ฐ ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ์ ์ฉ๋๊ฒ ํ๊ณ ์ถ๋ค๋ฉด,
ConfigurableWebBindingInitalizer๋ฅผ ์ค์ ํด์ ์ฌ์ฉ ํด์ผํ๋ค.
๋ง์ฝ ํน์ ์ปจํธ๋กค๋ฌ ๋ด๋ถ์์๋ง ์ ์ฉ๋๊ฒ ํ๊ณ ์ถ๋ค๋ฉด, PropertyEditor์ ๊ฐ์ด, ํด๋น ์ปจํธ๋กค๋ฌ ๋ด๋ถ์ ๋ณํ ๋งค์๋ ๋ง๋ค๊ณ ๊ทธ ๋งค์๋์ @InitBinder ์ด๋ ธํ ์ด์ ๋ถ์ด๋ฉด ๋๋ค.
(3) Formatter
์๊น Date Birth๋ก ์์ฒญ์ ํ๋ผ๋ฏธํฐ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์๋ค. ํ๋๋ ๋งค์๋ ๋ด๋ถ์ PropertyEditor๋ฅผ ์ฐ๋ ๋ฐฉ๋ฒ ์ด์๊ณ , ํ๋๋ ๋ฐ์ธ๋ฉ ํ๊ณ ์ ํ๋ ํ๋์ ์ด๋ ธํ ์ด์ ์ ์ฉํ์ฌ ๋ฐ๋ก ๋ฐ๊พธ๋ ๊ฒ์ด์๋ค.
Formatter๋ ์ฌ๊ธฐ์ ํ์์ ๋ฐฉ๋ฒ์ ๋งํ๋ค.
Formatter๋ PropertyEditor์ ๋ง์ฐฌ๊ฐ์ง๋ก ์๋ฐฉํฅ์ผ๋ก ๋ณํํ๋ค. (String -> ๋ค๋ฅธ ์๋ฃํ, ๋ค๋ฅธ ์๋ฃํ -> String)
@NuberFormat ์ ์ซ์๋ฅผ String์ผ๋ก, String์ ์ซ์๋ก ๋ณํํ๋ค.
@DateTimeFormat ์ ๋ ์ง๋ฅผ String์ผ๋ก, String์ ๋ ์ง๋ก ๋ณํํ๋ค.
ํด๋น ์ด๋ ธํ ์ด์ ์ ()์์ ๋ณํ ํด์ผํ๋ ํจํด์ ์ ์ด๋ฃ์ ์ ์๋ค.
์์๋ ๋ค์๊ณผ ๊ฐ๋ค.
// yyyy๋ ๋
์ผ๋ก, MM์ ์๋ก, dd๋ ์ผ๋ก ๋ณํํ์ฌ ๊ณ์ฐํ๋ผ.
// User ํด๋์ค ๋ด์ Birth ์ธ์คํด์ค ์ ์ธ ์์ ์ ์
@DateTimeFormat(pattern = "yyyy/MM//dd")
Date Birth;
// ###,###์ผ๋ก ๋ค์ด์จ ๊ฐ์ , ๋นผ๊ณ int๋ก ๋ณํํ๋ผ
@NumberFormat(pattern = "###,###")
BigDecimal salary;
(4)์ ์ฉ์ ์ฐ์ ์์
a. ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ์ ์ฉ๋๋ ๋ณํ ๋งค์๋ vs ํน์ ์ปจํธ๋กค๋ฌ ๋ด๋ถ์ ๋ณํ ๋งค์๋
์์ธ์ฒ๋ฆฌ ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก, ๋ณํ์ ํด์ผํ๋ ๊ณณ์์ ๊ฐ๊น์ด ์ชฝ์ ๋งค์๋๊ฐ ์ฐ์ ์ ์ผ๋ก ์๋ํ๋ค.
ํน์ ์ปจํธ๋กค๋ฌ ๋ด์์ ๋ฐ์ธ๋ฉ์ ์ํ ๋ณํ์ด ํ์ํ ๊ฒฝ์ฐ, ๊ทธ ์ปจํธ๋กค๋ฌ ๋ด๋ถ์ @initBinder๋ก ๋ฑ๋ก๋ ๋ณํ ๋งค์๋๊ฐ ์๊ณ , ๊ทธ ๋ ์์ด ๋ณํ์ ํ ์ ์์ผ๋ฉด, ์ด๋ ์์ด ์ฐ์ ์ด๋ค. ์ปจํธ๋กค๋ฌ ๋ด๋ถ์์ ํด๊ฒฐ์ด ์๋ ๋, ๋ชจ๋ ์ปจํธ๋กค๋ฌ์ ์ ์ฉ๋๋ ๋ณํ ๋งค์๋๋ฅผ ์ด์ฉํ๋ค.
b. ๋ณํ ๋งค์๋ ๋ด์ ๋ณํ ๊ธฐ๋ฅ์ ํ๋ ๊ฐ์ฒด๋ค ์ฌ์ด์ ์ฐ์ ์์
์ด๋ค ์ปจํธ๋กค๋ฌ ๋ด๋ถ์ ๋ฐ์ธ๋ฉ์ ์ํ ๋ณํ์ด ํ์ํ๋ค๊ณ ํด๋ณด์.
๋จผ์ Spring์ CustomPropertyEditor ์ค์ ์ด ๋ณํ์ ํด๊ฒฐํ ์ ์๋ ๋ ์์ด ์๋์ง ์ฐพ๋๋ค.
CustomPropertyEditor๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ตฌํํ PropertyEditor์ด๋ค.
์ฌ๊ธฐ์ ํด๊ฒฐ์ด ์๋๋ฉด, ๊ทธ ๋ค์์ Spring์ ๋ฑ๋ก๋ Converter์ธ CoversionService๋ฅผ ๋์๋ค๋๋ค.
์ด ๋ ์๋ค ์ค์๋ ํด๊ฒฐํ ๋ ์์ด ์์ผ๋ฉด DefaultPropertyEditor(Spring์ ๋ฑ๋ก๋ PropertyEditor) ์ค์ ํด๊ฒฐํ ๋ ์์ด ์๋ ์ฐพ์๋ณธ๋ค.
๋ฐ๋ผ์ ์ฐ์ ์์๋
1. ์ปค์คํ PE, 2. ConversionService, 3.๋ํดํธPE ์์ด๋ค.
4. ์ง์ ํด๋ณด๊ธฐ
(1) ์ปค์คํ PE, Formatter ์ง์ ์ณ๋ณด๊ธฐ
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("#"));
}
(2) Salary ์ถ๊ฐ ํด๋ณด๊ธฐ
@NumberFormat(pattern="###,###")
private int Salary;
public int getSalary() {
return Salary;
}
public void setSalary(int salary) {
Salary = salary;
}
<label for="">๋ด๊ธ</label>
<input class="input-field" type="text" name="Salary" placeholder="###,###">
<h1>Salary=${user.salary}</h1>