์คํ๋ง MVC 2ํธ์ ๊ฐ์ ๋ด์ฉ์ ์ ๋ฆฌํ ํฌ์คํ ์ ๋๋ค.
๊ฒ์ฆ
์ปจํธ๋กค๋ฌ์ ์ค์ํ ์ญํ ์ค ํ๋๋ HTTP ์์ฒญ์ด ์ ์์ธ์ง ๊ฒ์ฆํ๋ ๊ฒ์ด๋ค. ํด๋ผ์ด์ธํธ ๊ฒ์ฆ๋ง์ผ๋ก๋ ์กฐ์์ ๊ฐ๋ฅ์ฑ์ด ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ณด์์ ์ทจ์ฝํ๊ณ , ์๋ฒ๋ง์ผ๋ก ๊ฒ์ฆํ๋ฉด ์ฆ๊ฐ์ ์ธ ๊ณ ๊ฐ ์ฌ์ฉ์ฑ์ด ๋จ์ด์ง๋ค. ๋ฐ๋ผ์ ๋์ ์ ์ ํ ์์ด ์ฌ์ฉํ๋ ์ต์ข
์ ์ผ๋ก ์๋ฒ ๊ฒ์ฆ์ ๊ฑฐ์น๋๋ก ์ค๊ณํด์ผ ํ๋ค.
๊ฒ์ฆ ์ง์ ์ฒ๋ฆฌ
๋ก์ง
1. Map<String, String> errors = new HashMap<>();
์ ์ ์ธํ์ฌ ์ค๋ฅ๋ฅผ ๋ณด๊ดํ ๋ณ์๋ฅผ ์ง์ ํ๊ณ ๊ฒ์ฆ ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ ํ๋๋ช
์ key๋ก, ์ค๋ฅ ๋ฉ์์ง๋ฅผ value๋ก ์ ์ฅํ๋ค.(์ค๋ฅ ์์ธ์ด ํน์ ํ๋๊ฐ ์๋๋ผ ํ๋ ๋ฒ์๋ฅผ ๋์ด์๋ ์ค๋ฅ๋ผ๋ฉด globalError๋ฅผ key๋ก ์ฌ์ฉํ๋ค.) ์ดํ ๋ทฐ์์ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๊ณ ์ฌ์ฉ์์๊ฒ ์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํ ์ ์๋ค.
2. ๊ณ ๊ฐ์ด ์
๋ ฅํ ๋ฐ์ดํฐ๋ ๊ฒ์ฆ ์ค๋ฅ๊ฐ ๋ฐ์ํด๋ ์ ์ง๋์ด ๋ค์ ์
๋ ฅ ํผ์ ๋ณด์ฌ์ค ๋ ์ด์ฉ๋๋ค.
๋ฌธ์ ์
'๊ฐ๊ฒฉ์ 1000์ ์ด์์ด์ด์ผ ํ๋ค'์ ๊ฐ์ด ๊ท์น์ ๋ฐ๋ฅธ ๊ฒ์ฆ์ ๊ฐ๋ฅํ์ง๋ง, ํ์
์ค๋ฅ ์ฒ๋ฆฌ๊ฐ ๋ถ๊ฐ๋ฅํ๋ค. ๊ฐ๊ฒฉ์ ๊ฒ์ฆํ๊ธฐ ์ํด์๋ ํด๋น ํ๋์ ์ซ์๊ฐ ๋ค์ด์์ผ ํ๋ค. ๊ทธ๋ฐ๋ฐ ์ฌ์ฉ์๊ฐ ์ซ์ ํ๋์ ๋ฌธ์๋ฅผ ์
๋ ฅํ๋ค๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค.
์
๋ ฅ๊ฐ์ ์ปจํธ๋กค๋ฌ์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๊ธฐ ์ํด ์ซ์ ํ๋์ ๋ฌธ์๋ฅผ ๋์
ํ๋ ๊ณผ์ ์์ ๋ฐ์ํ๋ ์ค๋ฅ์ด๊ธฐ ๋๋ฌธ์, ์ ์ ๊ฒ์ฆ ๋ก์ง์ ๊ฐ์ง๊ณ ์๋ ์ปจํธ๋กค๋ฌ๋ ํธ์ถ๋์ง๋ ๋ชปํ๊ณ 400 ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค. ์ฆ, ํ๋์ ์
๋ ฅ ๊ฐ์ด ์๋ก ๋ค๋ฅธ ํ์
์ธ ๊ฒฝ์ฐ ๋ฐ์ธ๋ฉ์ด ๋ถ๊ฐ๋ฅํ๋ค.
์ด์ ๋ฐ๋ผ ์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ์ด ์ฌ๋ผ์ง๊ฒ ๋๋ฉด์ ์ด๋ค ๋ด์ฉ์ ์
๋ ฅํจ์ ๋ฐ๋ผ ๋ฐ์ํ ์ค๋ฅ์ธ์ง ์ดํดํ๊ธฐ ์ด๋ ค์ธ ์ ์์ผ๋ฏ๋ก ํด๋น ์
๋ ฅ ๊ฐ๋ ๊ด๋ฆฌ๊ฐ ํ์ํ ๊ฒฝ์ฐ๊ฐ ์๋ค.
BindingResult
์คํ๋ง์ด ์ ๊ณตํ๋ ๊ฒ์ฆ ๋ฐฉ๋ฒ์ ์์ ๋ฌธ์ ์ ์ ํด๊ฒฐํด ์ฃผ๋๋ฐ, ํต์ฌ์ BindingResult์ ์๋ค.
BindingResult๋ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ ๋ฐ ์ค๋ฅ๋ฅผ ๊ด๋ฆฌํ๋ ์ธํฐํ์ด์ค์ธ Errors๋ฅผ ์์๋ฐ๋ ์ธํฐํ์ด์ค๋ก, ๋ฐ์ธ๋ฉ ๊ฒฐ๊ณผ๋ฅผ ์ฒ๋ฆฌํจ์ผ๋ก์จ ๊ฒ์ฆ ์ค๋ฅ๋ฅผ ๋ณด๊ดํ๋ ๊ฐ์ฒด์ด๋ค. ํด๋น ๊ฐ์ฒด๋ DataBinder ํด๋์ค์ getBindingResult()
๋ฉ์๋๋ฅผ ํตํด ์์ฑ๋ ์๋ ์๊ณ , ์ง์ ์ ์ผ๋ก ๊ตฌํ๋ ์๋ ์๋ค.
๊ท์น์ด ์๋ค๋ฉด BindingResult๋ฅผ ์ปจํธ๋กค๋ฌ๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธธ ๋ ์ฌ์ฉ์์ ์
๋ ฅ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ํ๋ผ๋ฏธํฐ์ ๋ฐ๋ก ๋ค์์ ์์ผ ํ๋ค๋ ๊ฒ์ด๋ค.
FieldError, ObjectError ํด๋์ค
BindingResult๋ addError()
๋ฉ์๋๋ฅผ ์ด์ฉํด ์ง์ ์๋ฌ๋ฅผ ์ถ๊ฐํ ์ ์๋๋ก ๊ตฌํํด ๋์๋๋ฐ, ์ด๋ addError()
์ ํ๋ผ๋ฏธํฐ๋ก ๋ค์ด๊ฐ๋ ํ์
์ ObjectError์ด๋ค.
ObjectError๋ ์ค๋ฅ ๋ฐ์ ์์ธ์ด ํน์ ํ๋์ ์๋ ๊ฒ์ด ์๋ ์ ์ฒด ์์ธ(global error)์ธ ๊ฒฝ์ฐ๊น์ง๋ ์บก์ํํ๋ค. ๊ทธ์ ๋ฐํด FieldError๋ ํน์ ํ๋์ ์ํด ๋ฐ์ํ ์ค๋ฅ๋ฅผ ์บก์ํํ๋ ํด๋์ค๋ก, ObjectError๋ฅผ ์์๋ฐ๋๋ค.
๊ฐ ํด๋์ค์ ์์ฑ์๋ ๋ค์๊ณผ ๊ฐ๋ค.
public ObjectError(
String objectName, //์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ์ฒด ์ด๋ฆ
String defaultMessage //๊ธฐ๋ณธ ์ค๋ฅ ๋ฉ์์ง
)
public ObjectError(
String objectName,
@Nullable String[] codes, //๋ฉ์์ง ์ฝ๋
@Nullable Object[] arguments, //๋ฉ์์ง์์ ์ฌ์ฉํ๋ ์ธ์
@Nullable String defaultMessage
)
public FieldError(
String objectName,
String field, //์ค๋ฅ ํ๋
String defaultMessage
)
public FieldError(
String objectName,
String field,
@Nullable Object rejectedValue, //์ฌ์ฉ์๊ฐ ์
๋ ฅํ ๊ฐ(๊ฑฐ์ ๋ ๊ฐ)
boolean bindingFailure, //ํ์
์ค๋ฅ์ ๊ฐ์ ๋ฐ์ธ๋ฉ ์คํจ์ธ์ง, ๊ฒ์ฆ ์คํจ์ธ์ง์ ๋ํ ๊ตฌ๋ถ ๊ฐ
@Nullable String[] codes,
@Nullable Object[] arguments,
@Nullable String defaultMessage
)
BindingResult์ ๊ฒ์ฆ ์ค๋ฅ๋ฅผ ์ ์ฉํ๋ ๋ฐฉ๋ฒ
1. ์คํ๋ง์ด FieldError๋ฅผ ์์ฑํ์ฌ ์ฃผ์
(@ModelAttribute
์ ๊ฐ์ฒด์ ํ์
์ค๋ฅ ๋ฑ์ผ๋ก ๋ฐ์ธ๋ฉ์ ์คํจํ๋ ๊ฒฝ์ฐ)
2. ๊ฐ๋ฐ์๊ฐ ์ง์ ์ฃผ์
(๋ฐ์ธ๋ฉ์๋ ์ฑ๊ณตํ์ผ๋ ๋น์ฆ๋์ค ๋ก์ง ์กฐ๊ฑด์ ์ ๋ง๋ ๊ฒฝ์ฐ)
3. Validator ์ฌ์ฉ
์ค๋ฅ ์ฝ๋์ ๋ฉ์์ง ์ฒ๋ฆฌ
v1. FieldError, ObjectError ์ด์ฉ
@PostMapping("/add")
public String addItemV1(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.addError(new FieldError("item", "price", item.getPrice(), false, new String[]{"range.item.price"}, new Object[]{1000, 1000000}, null));
}
}
ํด๋น ์์์ codes ํ๋ผ๋ฏธํฐ(range.item.price
)๋ ์๋ฌ ๋ฉ์์ง๋ฅผ ๊ด๋ฆฌํ๋ properties ํ์ผ์ ์ถ๊ฐ๋ ๋ฉ์์ง ์ฝ๋๋ก, ๊ฐ๊ฒฉ์ ์ ํจ ๋ฒ์๋ฅผ ๋ฒ์ด๋ฌ์์ ์๋ฆฌ๋ ๋ฉ์์ง๋ฅผ ๋ด๊ณ ์๋ค.
v2. BindingResult๊ฐ ์ ๊ณตํ๋ ๋ฉ์๋ ์ด์ฉ & ์ค๋ฅ ์ฝ๋ ์๋ํ
v1์์๋ BindingResult ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ์ํด FieldError ๋๋ ObjectError ๊ฐ์ฒด๋ฅผ ์ง์ ์์ฑํ ๋ค ๋๊ฒจ์ฃผ๋ ๊ณผ์ ์ด ํ์ํ๋ค.
ํ์ง๋ง BindException์ด ์ ๊ณตํ๋ ๋ฉ์๋์ธ rejectValue()
, reject()
๋ฅผ ์ด์ฉํ๋ฉด ์ฝ๋๋ฅผ ๋จ์ํํ ์ ์๋ค.
(BindException์ BindingResult์ ๊ตฌํ์ฒด)
public void rejectValue(
@Nullable String field, //์ค๋ฅ ํ๋๋ช
String errorCode, //MessageResolver๊ฐ ์๋ณํ๋ ์ค๋ฅ ์ฝ๋
@Nullable Object[] errorArgs, //์ค๋ฅ ๋ฉ์์ง์ ํ๋ผ๋ฏธํฐ ๊ฐ
@Nullable String defaultMessage //์ค๋ฅ ๋ฉ์์ง๋ฅผ ์ฐพ์ ์ ์์ ๋ ์ฌ์ฉํ๋ ๊ธฐ๋ณธ ๋ฉ์์ง
)
์ค๋ฅ ๋ฐ์ ์์ธ์ ๋ฐ๋ผ FieldError ๋๋ ObjectError๋ฅผ ์ ํํ๋ฏ์ด ํ๋์ ์ํ ์ค๋ฅ์ธ ๊ฒฝ์ฐ rejectValue()
๋ฅผ, ๊ทธ ์ธ ํฌ๊ด์ ์ธ ์ค๋ฅ์ธ ๊ฒฝ์ฐ reject()
๋ฅผ ์ ํํ๋ฉด ๋๋ค.
@PostMapping("/add")
public String addItemV2(@ModelAttribute Item item, BindingResult bindingResult, RedirectAttributes redirectAttributes, Model model) {
if (item.getPrice() == null || item.getPrice() < 1000 || item.getPrice() > 1000000) {
bindingResult.rejectValue("price", "range", new Object[]{1000, 1000000}, null);
}
}
FieldError๋ฅผ ์์ฑํ ๋ item ๊ฐ์ฒด๋ฅผ ๋๊ฒจ์ค ๊ฒ๊ณผ ๋ฌ๋ฆฌ rejectValue()
๋ฉ์๋์์๋ ๊ฐ์ฒด๋ฅผ ๋๊ธฐ์ง ์๊ณ ๋ ์ ์์ ์ผ๋ก ๋์ํ๋ค.
BindingResult๋ ๊ฒ์ฆํด์ผ ํ ๊ฐ์ฒด์ ๋ฐ๋ก ๋ค์์ผ๋ก ๋ฐ๋ผ์ค๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ ๊ฒ์ฆํด์ผ ํ ๊ฐ์ฒด๋ฅผ ์๊ณ ์๋ค. ๋ฐ๋ผ์ ๊ฐ์ฒด๋ฅผ ์ง์ ์ฃผ์
ํด์ฃผ์ง ์์๋ ํ์
์ด ๊ฐ๋ฅํ ๊ฒ์ด๋ค.
์ค๋ฅ ์ฝ๋(๋ฉ์์ง)์ ์ฐ์ ์์
v2์์ ๋ฐ๋ ์ ์ด ๋ค๋ฅธ ๋ฉ์๋๋ฅผ ์ด์ฉํ ๊ฒ๋ ์์ง๋ง ๋ฉ์๋๊ฐ ๋ฐ๋๊ณผ ๋์์ ์ค๋ฅ ์ฝ๋๊ฐ ๋จ์ํ๋์์์ ์ ์ ์๋ค.
(range.item.price
โ range
)
ํ์ง๋ง ๋์์๋ ๋ฌธ์ ๊ฐ ์๋๋ฐ, ์ด๋ MessageCodesResolver๊ฐ ์ค๋ฅ๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ฐ๋ฅธ ๊ฒฐ๊ณผ์ด๋ค.
์ค๋ฅ ์ฝ๋๋ฅผ ๋ง๋ค ๋ ์์ธํ ๋ง๋ค ์๋ ์๊ณ , ๋จ์ํ๊ฒ ๋ง๋ค ์๋ ์๋ค.
range: ๋ฒ์ ์ค๋ฅ ์
๋๋ค. //ํฌ๊ด์
range.item.price: ์ํ์ ๊ฐ๊ฒฉ ๋ฒ์ ์ค๋ฅ์
๋๋ค. //๊ตฌ์ฒด์
๋จ์ํ๊ฒ ๋ง๋ค๋ฉด ๋ฒ์ฉ์ฑ์ด ์ข์ ๋๋ฃจ ์ฌ์ฉํ ์ ์์ง๋ง, ๋ฉ์์ง๋ฅผ ์ธ๋ฐํ๊ฒ ์์ฑํ๊ธฐ ์ด๋ ต๋ค. ๋ฐ๋๋ก ๋๋ฌด ์์ธํ๊ฒ ๋ง๋ค๋ฉด ๋ฒ์ฉ์ฑ์ด ๋จ์ด์ง๋ค. ๋ฐ๋ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก๋ ๋ฒ์ฉ์ฑ์ผ๋ก ์ฌ์ฉํ๋ค๊ฐ ์ธ๋ฐํ๊ฒ ์๋ดํด์ผ ํ๋ ๊ฒฝ์ฐ ๊ตฌ์ฒด์ ์ธ ๋ด์ฉ์ด ์ ์ฉ๋๋๋ก ๋ฉ์์ง์ ๋จ๊ณ๋ฅผ ๋๋ ๋ฐฉ๋ฒ์ ์ฑํํ ์ ์๋ค.
๋ง์ฝ range
๋ผ๋ ๋ฉ์์ง๋ง ์์๋ค๋ฉด ํด๋น ๋ฉ์์ง๋ฅผ ์ ํํด์ ์ฌ์ฉํ๊ณ , range.item.price
์ ๊ฐ์ด ๊ฐ์ฒด๋ช
๊ณผ ํ๋๋ช
์ ์กฐํฉํ ์ธ๋ฐํ ๋ฉ์์ง ์ฝ๋๊ฐ ์์ ๊ฒฝ์ฐ ํด๋น ๋ฉ์์ง๋ฅผ ๋์ ์ฐ์ ์์๋ก ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
MessageCodesResolver
๊ทธ๋ ๋ค๋ฉด MessageCodesResolver ์ธํฐํ์ด์ค๊ฐ ์ด๋ป๊ฒ ์ค๋ฅ๋ฅผ ๊ตฌ์ฑํ๋์ง ์ดํด๋ณด์.
ํด๋น ์ธํฐํ์ด์ค๋ ๊ฒ์ฆ ์ค๋ฅ ์ฝ๋๋ก ๋ฉ์์ง ์ฝ๋๋ฅผ ์์ฑํ๋ฉฐ ์ฃผ๋ก ObjectError, FieldError์ ํจ๊ป ์ฌ์ฉ๋๋ค.
1. ๊ธฐ๋ณธ ๋ฉ์์ง ์์ฑ ๊ท์น - ObjectError
๊ฐ์ฒด ์ค๋ฅ์ ๊ฒฝ์ฐ ๋ค์ ์์๋ก 2๊ฐ์ง ์์ฑ
1.: code + "." + object name
2.: code
์) ์ค๋ฅ ์ฝ๋: required, object name: item
1.: required.item
2.: required
2. ๊ธฐ๋ณธ ๋ฉ์์ง ์์ฑ ๊ท์น - FieldError
ํ๋ ์ค๋ฅ์ ๊ฒฝ์ฐ ๋ค์ ์์๋ก 4๊ฐ์ง ๋ฉ์์ง ์ฝ๋ ์์ฑ
1.: code + "." + object name + "." + field
2.: code + "." + field
3.: code + "." + field type
4.: code
์) ์ค๋ฅ ์ฝ๋: typeMismatch, object name "user", field "age", field type: int
1. "typeMismatch.user.age"
2. "typeMismatch.age"
3. "typeMismatch.int"
4. "typeMismatch"
rejectValue()
, reject()
๋ ๋ด๋ถ์์ MessageCodesResolver๋ฅผ ์ฌ์ฉํด ๋ฉ์์ง ์ฝ๋๋ฅผ ์์ฑํ๋ค. ObjectError, FieldError์ ์์ฑ์๋ฅผ ๋ณด๋ฉด String[] ํ์
์ผ๋ก, ์ค๋ฅ ์ฝ๋๋ฅผ ์ฌ๋ฌ ๊ฐ ๊ฐ์ง ์ ์์์ ์ ์ ์๋ค. ๋ฐ๋ผ์ ์ฐ์ ์์์ ๋ฐ๋ผ ์์๋๋ก ์ฝ๋๋ฅผ ๋ณด๊ดํ ์ ์๋ค.
์ค๋ฅ ์ฝ๋ ๊ด๋ฆฌ ์ ๋ต
ํต์ฌ์ ๊ตฌ์ฒด์ ์ธ ๊ฒ์์ ๋ ๊ตฌ์ฒด์ ์ธ ๊ฒ์ผ๋ก, ์ฆ ๊ตฌ์ฒด์ ์ธ ๊ฒ์ ๋จผ์ ๋ง๋ค์ด์ฃผ๊ณ ๋ ๊ตฌ์ฒด์ ์ธ ๊ฒ์ ๋์ค์ ๋ง๋ค๊ฒ ๋๋ฉด ๋ฉ์์ง ๊ณตํต ์ ๋ต์ ํธ๋ฆฌํ๊ฒ ๋์
ํ ์ ์๋ค.
๋ชจ๋ ์ค๋ฅ ์ฝ๋์ ๋ํด ์ผ์ผ์ด ๋ฉ์์ง๋ฅผ ์ ์ํ๋ฉด ๊ด๋ฆฌํ๊ธฐ๊ฐ ์ด๋ ต๋ค. ๋ฐ๋ผ์ ํฌ๊ฒ ์ค์ํ์ง ์์ ๋ฉ์์ง๋ ๋ฒ์ฉ์ฑ ์๋ ์ฝ๋๋ก ๋๋ด๊ณ , ์ค์ํ ๋ฉ์์ง๋ ๊ตฌ์ฒด์ ์ผ๋ก ์ ์ด ์ฌ์ฉํ๋ ๋ฐฉ์์ด ํจ๊ณผ์ ์ด๋ค. ๋ฒ์ฉ์ฑ ์๋ ์ฝ๋๋ ์ฌํ์ฉ์ด ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
์คํ๋ง์ด ์ง์ ๋ง๋ ์ค๋ฅ ๋ฉ์์ง ์ฒ๋ฆฌ
๊ฒ์ฆ ์ค๋ฅ ์ฝ๋๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ์ค์ ํ ์ค๋ฅ ์ฝ๋์ ์คํ๋ง์ด ์ง์ ๊ฒ์ฆ ์ค๋ฅ์ ์ถ๊ฐํ ๊ฒฝ์ฐ, 2๊ฐ์ง๋ก ๋๋ ์ ์๋ค.
ํ์์ ๊ฒฝ์ฐ ํ์
์ด ๋ง์ง ์์ ๋ฐ์ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์๋ฐ, ํด๋น ์ํฉ์์๋ FieldError๊ฐ ํธ์ถ๋จ์ ๋ฐ๋ผ 4๊ฐ์ ๋ฉ์์ง ์ฝ๋๊ฐ ์์ฑ๋ ๊ฒ์ด๋ค.
properties ํ์ผ์ typeMismatch์ ๊ด๋ จ๋ ๋ฉ์์ง๋ฅผ ๋ฑ๋กํ์ง ์์๋ค๋ฉด ์คํ๋ง์ด ์์ฑํ ๊ธฐ๋ณธ ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๊ณ , ๋ฑ๋กํ ๊ฒฝ์ฐ ์ํ๋ ๋ฉ์์ง๋ฅผ ๋จ๊ณ๋ณ๋ก ์ค์ ํ์ฌ ์ถ๋ ฅํ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
v3. Validator ๋ถ๋ฆฌ
์ปจํธ๋กค๋ฌ์์ ๊ฒ์ฆ ๋ก์ง์ด ์ฐจ์งํ๋ ๋ถ๋ถ์ ๋งค์ฐ ํฌ๊ธฐ ๋๋ฌธ์, ๋ณ๋์ ํด๋์ค๋ก ์ญํ ์ ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ข๋ค.
์คํ๋ง์ ๊ฒ์ฆ์ ์ฒด๊ณ์ ์ผ๋ก ์ ๊ณตํ๊ธฐ ์ํด ๋ค์ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๋ค.
public interface Validator {
boolean supports(Class<?> clazz);
void validate(Object target, Errors errors);
}
๊ฒ์ฆ ์ญํ ์ ์ํํ๋ ํด๋์ค๋ฅผ ์ง์ ๋ง๋ค์ด ์ปจํธ๋กค๋ฌ ๋ด ๋ฉ์๋์์ ์ง์ ํธ์ถํ ์๋ ์์ง๋ง, ํด๋น ์ธํฐํ์ด์ค๋ฅผ ์ด์ฉํด ๋ง๋ค๋ฉด ๊ฒ์ฆ๊ธฐ๋ฅผ ์ง์ ํธ์ถํ๋ ๊ณผ์ ์ ์๋ตํ ์ ์๋ค.
๋จผ์ WebDataBinder์ ๊ฒ์ฆ๊ธฐ๋ฅผ ๋ฑ๋กํด์ผ ํ๋๋ฐ, ์ฌ๊ธฐ์ WebDataBinder๋ ์น ์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ์๋ฐ ๋น ๊ฐ์ฒด์ ๋ฐ์ธ๋ฉํ๋ ์ญํ ์ ์ํํ๋ค. ๋ค์๊ณผ ๊ฐ์ด Validator ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ๊ฒ์ฆ๊ธฐ๋ฅผ ๋ง๋ค ์ ์๋ค.
@Component
public class ItemValidator implements Validator {
@Override
public boolean supports(Class<?> clazz) {
return Item.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors) {
//๊ฒ์ฆ ๋ก์ง
}
}
๊ฒ์ฆ์ ์ํํ๋ ค๋ ๊ฐ์ฒด ์์ @Validated
์ ๋
ธํ
์ด์
์ ๋ถ์ฌ์ฃผ๋ฉด WebDataBinder์ ๋ฑ๋กํ ๊ฒ์ฆ๊ธฐ๋ฅผ ์ฐพ์ ๋์ ์คํํด ์ค๋ค. ๊ทธ์ ์ ์ด๋ค ๊ฒ์ฆ๊ธฐ๋ฅผ ์คํํ ๊ฒ์ธ์ง์ ๋ํ ๊ตฌ๋ถ์ด ํ์ํ๋ฐ, ์ด๋ supports()
๋ฉ์๋๋ฅผ ํตํด ๊ฒ์ฆ๊ธฐ ์ง์ ์ฌ๋ถ๋ฅผ ํ์ธํ์ฌ ๊ณจ๋ผ๋ผ ์๊ฐ ์๋ค. ๊ฒฐ๊ณผ๋ก true๊ฐ ๋ฐํ๋ ๊ฒฝ์ฐ validate ๋ฉ์๋๊ฐ ํธ์ถ๋์ด ๊ฒ์ฆ์ ์ํํ๋ค.
@PostMapping("/add")
public String addItemV3(@Validated @ModelAttribute Item item, BindingResult bindingResult) {
}
@Validated
๋์ @Valid
๋ฅผ ์ฌ์ฉํ ์๋ ์๋ค. @Validated
๋ ์คํ๋ง ํ์ค, @Valid
๋ ์๋ฐ ํ์ค ๊ฒ์ฆ ์ ๋
ธํ
์ด์
์ธ๋ฐ @Valid
๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ build.gradle
์ ์์กด๊ด๊ณ๋ฅผ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค๋ ์ฐจ์ด์ ์ด ์กด์ฌํ๋ค.
'Language & Framework > Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์คํ๋ง MVC] ๋ก๊ทธ์ธ ์ฒ๋ฆฌ(1) - ์ฟ ํค, ์ธ์ (0) | 2023.03.02 |
---|---|
[์คํ๋ง MVC] ๊ฒ์ฆ(2) - Bean Validation (0) | 2023.02.21 |
[์คํ๋ง MVC] ๋ฉ์์ง, ๊ตญ์ ํ (0) | 2023.02.11 |
[์คํ๋ง MVC] ๊ธฐ๋ณธ ๊ธฐ๋ฅ (0) | 2023.02.05 |
[์คํ๋ง MVC] ์คํ๋ง MVC ๊ตฌ์กฐ ์ดํด (0) | 2023.02.03 |