์คํ๋ง Bean Validation
Categories: spring
Tags: spring, validation
๊ฒ์ฆ๋ก์ง์ ๋งค๋ฒ ์ฝ๋๋ก ์์ฑํ๋ ์ผ์ ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํ ์ผ์ด ๋๋ฌด ๋ง๋ค. ๊ฒ์ฆ์ ๋๋ถ๋ถ์ ํ๋์ ๊ฐ์ ๋ํ ๊ฒ์ฆ์ด๋ ๋น ๊ฐ์ธ์ง, ์ด๊ณผ์ธ์ง, ๋ฏธ๋ง์ธ์ง๋ฑ์ ์ผ๋ฐ์ ์ธ ๋ก์ง์ด๋ค. ์ด ๊ฒ์ฆ๋ค์ ์คํ๋ง์ ํตํด ์ด๋ ธํ ์ด์ ๊ธฐ๋ฐ์ผ๋ก ์ฝ๊ฒ ๊ฒ์ฆํ ์ ์๋ค.
Bean Validation
Bean Validation์ ํน์ ํ ๊ตฌํ์ฒด๊ฐ ์๋๋ผ Bean Validation 2.0(JSR-380)์ด๋ผ๋ ๊ธฐ์ ํ์ค์ด๋ค. ๊ตฌํ์ฒด๋ก๋ Hibernate์ Validator๋ฅผ ์ฌ์ฉํ๋ค.
Validation์ ๋ชจ๋ application layer์์ ์ ์ฉ๋๋ค. ์๋์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ ๋ฐฉ์์ ์ค๋ณต๋๋ validation์ด ์์ ์ ์๋ค.
์ถ์ฒ : https://docs.jboss.org/hibernate/validator/8.0/reference/en-US/html_single/#preface
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ validation ๋ก์ง์ ๋๋ฉ์ธ ์์ญ์ ๋ฌถ์ด์ ํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ํํํ ์ ์๋ค.
๊ฒ์ฆ ์ ๋ ธํ ์ด์
์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ์ ๋ฐฉ์์ ํตํด ๋ฐ๋ก ์ง๊ด์ ์ผ๋ก ์ดํด๋๊ฒ ๊ฒ์ฆ ๋ก์ง์ ๋ง๋ค ์ ์๋ค.
- @NotBlank: ๋น๊ฐ + ๊ณต๋ฐฑ์ธ ๊ฒฝ์ฐ ํ์ฉํ์ง ์๋๋ค.
- @NotNull : null ์ ํ์ฉํ์ง ์๋๋ค.
- @Range(min = 1000, max = 1000000) : ๋ฒ์ ์์ ๊ฐ์ด์ด์ผ ํ๋ค.
- @Max(9999) : ์ต๋ 9999๊น์ง๋ง ํ์ฉํ๋ค.
@NotBlank
private String itemName;
@NotNull
@Range(min = 1000, max = 1000000)
private Integer price;
@NotNull
@Max(9999)
private Integer quantity;
๊ฒ์ฆ๊ธฐ ๊บผ๋ด๊ธฐ
Validation ๊ตฌํ์ฒด์์ validator๋ฅผ ๊บผ๋ด์ ์ฌ์ฉํ ์ ์๋ค. ์คํ๋ง์ ์ฌ์ฉํ๋ฉด ๋น์ ํตํด ๋ฑ๋ก๋จ์ผ๋ก ์๋์ ์ฝ๋๋ฅผ ์์จ๋ ๋๋ค.
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<Item>> violations = validator.validate(item); // ๊ฒ์ฆ์ ๊ฑธ๋ฆฐ ๋ก์ง๋ค์ด ๋ฐํ๋๋ค.
violation={interpolatedMessage='๊ณต๋ฐฑ์ผ ์ ์์ต๋๋ค', propertyPath=itemName, rootBeanClass=class hello.itemservice.domain.item.Item, messageTemplate='{javax.validation.constraints.NotBlank.message}'} violation.message=๊ณต๋ฐฑ์ผ ์ ์์ต๋๋ค
์คํ๋ง MVC ๊ฒ์ฆ
์คํ๋ง ๋ถํธ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ, spring-boot-starter-validation ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฃ์ผ๋ฉด ์๋์ผ๋ก Bean Validator๋ฅผ ์คํ๋ง์ ํตํฉํ๋ค.
์คํ๋ง ๋ถํธ๋ LocalValidatorFactoryBean๋ฅผ ๊ธ๋ก๋ฒ Validator๋ก ๋ฑ๋กํ๊ธฐ ๋๋ฌธ์, ๊ฒ์ฆ์ ํ๋ ค๋ ๊ณณ์ @Validated๋ง ์์ฑํ๋ฉด ๋๋ค. ๊ฒ์ฆ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ฉด FieldError, ObjectError๋ฅผ ์์ฑํด์ BindingResult์ ๋ด์์ค๋ค.
Bean Validation ์๋ฌ ์ฝ๋
์คํ๋ง์ ์ค๋ฅ ์ฝ๋๋ฅผ ๊ธฐ๋ฐ์ผ๋ก MessageCodesResolver ๋ฅผ ํตํด ๋ค์ํ ๋ฉ์์ง ์ฝ๋๊ฐ ์์๋๋ก ์์ฑ๋๋ค.
@NotBlank
NotBlank.item.itemName NotBlank.itemName NotBlank.java.lang.String NotBlank
BeanValidation๋ ๋ค์๊ณผ ๊ฐ์ ์์๋ก ๋ฉ์์ง๋ฅผ ์ฐพ๋๋ค.
- ์์ฑ๋ ๋ฉ์์ง ์ฝ๋ ์์๋๋ก messageSource ์์ ๋ฉ์์ง๋ฅผ ์ฐพ๋๋ค.
- ์ ๋ ธํ ์ด์ ์ message ์์ฑ ์ฌ์ฉ @NotBlank(message = โ๊ณต๋ฐฑ! {0}โ)
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ณธ ๊ฐ ์ฌ์ฉ
์ํฉ๋ณ ๋๋ฉ์ธ ์ ์ฝ์กฐ๊ฑด์ด ๋ค๋ฅธ ๊ฒฝ์ฐ
๋ฐ์ดํฐ๋ฅผ ๋ฑ๋กํ ๋์ ์์ ํ ๋ ์ ์ฝ์กฐ๊ฑด์ด ๋ค๋ฅธ ๊ฒฝ์ฐ๋ ๋ณ๋์ ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ํฉ๋ณ๋ก validation์ ๋ค๋ฅด๊ฒ ๋ง๋ค์ด ์ฃผ์ด์ผ ํ๋ค.
ํผ ๋ฐ์ดํฐ ์ ๋ฌ์ ์ํ ๋ณ๋์ ๊ฐ์ฒด ์ฌ์ฉ์ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์งํ๋๋ค.
** HTML Form -> ํน์ ํผ -> Controller -> ๋๋ฉ์ธ ์์ฑ ๋ฐ ๋ฐ์ดํฐ ์ถ๊ฐ -> Repository **
ํน์ ํผ์ ๋ง๋ค์ด์ผํ๊ณ , ๊ฐ์ฒด ์์ฑํ๋ ๊ณผ์ ์ด ์๋ค. ์ ์กํ๋ ํผ ๋ฐ์ดํฐ๊ฐ ๋ณต์กํด๋ ๊ฑฐ๊ธฐ์ ๋ง์ถ ๋ณ๋์ ํผ ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ ์๋ค. ๋ํ, ๋ณ๋์ ํผ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ธฐ ๋๋ฌธ์ ๊ฒ์ฆ์ด ์ค๋ณต๋์ง ์๋๋ค.
HttpMessageConverter
@Validated๋ @RequestBody์๋ ์ ์ฉํ ์ ์๋ค.
- @ModelAttribute : HTTP์์ฒญ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ค๋ฃฐ ๋ ์ฌ์ฉํ๋ค. => URL query string, POST form
- @RequestBody : HTTP Body ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ณํํ ๋ ์ฌ์ฉ
API ์์ฒญ์ ๊ฒฝ์ฐ 3๊ฐ์ง์ ๊ฒฝ์ฐ๊ฐ ์๋ค.
- ์ฑ๊ณต : ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋๋ฐ๋ ๋ฌธ์ ๊ฐ ์์๊ณ , ๊ฒ์ฆ์๋ ๋ฌธ์ ๊ฐ ์๋ ๊ฒฝ์ฐ
- ์คํจ : JSON ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด๋ก ๋ง๋๋ ๊ณผ์ ์์ ๋ฌธ์ ๊ฐ ์๊ธฐ๋ ๊ฒฝ์ฐ
- ๊ฒ์ฆ ์คํจ : ๊ฐ์ฒด๋ ๋ง๋ค์์ง๋ง, ๊ฒ์ฆ์ ์คํจํ ๊ฒฝ์ฐ
@ModelAttribute๋ ํน์ ํ๋๊ฐ ๋ฐ์ธ๋ฉ ๋์ง ์์๋ ๋๋จธ์ง ํ๋๋ ์ ์ ๋ฐ์ธ๋ฉ ๋๋ค. @RequestBody๋ JSON ๋ฐ์ดํฐ์์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ง ๋ชปํ๋ฉด ๊ฒ์ฆ ๋จ๊ณ์ ๋๋ฌํ์ง ๋ชปํ๋ค.
Leave a comment