Bean Validation๋?
์ ๋ ฅ๋ ๊ฐ์ด ์ ํจํ์ง ๊ฒ์ฌํ๋ ๋๊ตฌ
ํด๋ผ์ด์ธํธ๊ฐ ์ ๋ ฅํ ๊ฐ์ด ๋น์ด์๊ฑฐ๋ ํ์์ด ์๋ชป๋๊ฑฐ๋ ๋ฒ์์์ ๋ฒ์ด๋๋ฉด ๋ฐฑ์๋๊ฐ ๊ฑธ๋ฌ๋ด๊ณ ์๋ฌ๋ฉ์์ง๋ฅผ ์๋ ค์ค์ผ ํจ
์ ํ์ํ๊ฐ
- ๊ฒ์ฆ์ ์ํ๋ฉด?
์ฌ์ฉ์ ์ ๋ ฅ๊ฐ์ด DB์ ์ด์ํ๊ฒ ๋ค์ด๊ฐ๊ฑฐ๋
์๋ฒ๊ฐ ์์ ํฐ์ง๊ฑฐ๋
์์ธ(์๋ฌ)๊ฐ ๋ฐ์ํด์ ์ฑ์ด ๋จนํต์ด ๋จ
- ๊ฒ์ฆํ๋ฉด?
์๋ชป๋ ์ ๋ ฅ์ ๋ฏธ๋ฆฌ ๊ฑธ๋ฌ์ ์ฌ์ฉ์์๊ฒ ํผ๋๋ฐฑ
์๋ฒ๋ ์์ ํ๊ฒ ์๋๋จ
Bean Validation ์ ์ฉ ํ๋ฆ
์ ๋ ฅ๊ฐ -> DTO ๊ฐ์ฒด๋ก ๋ฐ์ธ๋ฉ๋จ
-> ๊ฒ์ฆ ์ด๋ ธํ ์ด์ (@NotBlank ๋ฑ)์ด ๋ถ์ฌ์์
-> ์คํ๋ง์ด ์๋์ผ๋ก ๊ฒ์ฌ
-> ์ค๋ฅ ๋๋ฉด BindingResult์ ๋ด๊น
-> Controller์์ ์ค๋ฅ ์ฒ๋ฆฌ
์์ ์ฝ๋ ๋ฐ๋ก๊ฐ์ฃ~
1) DTO๋ง๋ค๊ธฐ
// SignUpRequestDto.java
package com.example.demo.dto;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import org.hibernate.validator.constraints.Range;
import lombok.Getter;
@Getter
public class SignUpRequestDto {
// null, "", " " ์ ๋ถ ์ ๋จ
@NotBlank(message = "์ด๋ฆ์ ํ์์
๋๋ค.")
private String name;
// null์ด๋ฉด ์ ๋จ
@NotNull(message = "๋์ด๋ ํ์์
๋๋ค.")
// ์ซ์ ๋ฒ์ ์ ํ
@Range(min = 1, max = 120, message = "๋์ด๋ 1~120 ์ฌ์ด์ฌ์ผ ํฉ๋๋ค.")
private Integer age;
}
ํ์ํ ์ด์ ๋
ํด๋ผ์ด๋ํธ๊ฐ ๋น ๊ฐ์ด๋ ์๋ชป๋ ๊ฐ์ ๋ณด๋ด๋ ์ฐ๋ฆฌ๊ฐ if๋ฌธ์ผ๋ก ๋งค๋ฒ ๊ฒ์ฌํ์ง ์์๋ ์๋์ผ๋ก ๊ฒ์ฌํด์ค
2) Controller ๋ง๋ค๊ธฐ
// BeanValidationController.java
package com.example.demo.controller;
import com.example.demo.dto.SignUpRequestDto;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
@Slf4j
@Controller
public class BeanValidationController {
@PostMapping("/signup")
public String signup(
// @Valid → ์ด DTO๋ฅผ ์๋๊ฒ์ฆ
@Valid SignUpRequestDto requestDto,
// ๊ฒ์ฆ ๊ฒฐ๊ณผ๋ฅผ ๋ด๋ ๊ฐ์ฒด (๋ฌด์กฐ๊ฑด DTO ๋ค์์ ์์น)
BindingResult bindingResult,
// Thymeleaf ํ
ํ๋ฆฟ์ ๋ฐ์ดํฐ ๋๊ธฐ๊ธฐ์ฉ
Model model
) {
if (bindingResult.hasErrors()) {
// ๊ฒ์ฆ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ์ฌ๊ธฐ๋ก ์ด
log.info("์๋ฌ ๋ฐ์: {}", bindingResult.getAllErrors());
// error.html ๋ฐํ
return "error";
}
// ์ ํจ์ฑ ํต๊ณผํ ๊ฒฝ์ฐ
model.addAttribute("name", requestDto.getName());
model.addAttribute("age", requestDto.getAge());
// complete.html ๋ฐํ
return "complete";
}
}
์ @Valid ๋ BindingResult๊ฐ ์์ด์ผ ํ ๊น?
- @Valid๊ฐ ๊ฒ์ฆ์ ์ํํ๊ณ ๊ทธ ๊ฒฐ๊ณผ๋ฅผ BindingResult ๊ฐ ๋ด๊ธฐ ๋๋ฌธ
- ์ค๋ฅ๊ฐ ์์ผ๋ฉด if(bindingResult.hasError())์กฐ๊ฑด๋ฌธ์ด true๊ฐ ๋ผ์ ์๋ฌ ํ์ด์ง๋ก ๋ณด๋
3) ํ ํ๋ฆฟ
<!-- complete.html -->
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>ํ์๊ฐ์
์๋ฃ</title>
</head>
<body>
<h1>ํ์๊ฐ์
์ฑ๊ณต!</h1>
<p>์ด๋ฆ: <span th:text="${name}"></span></p>
<p>๋์ด: <span th:text="${age}"></span></p>
</body>
</html>
๋น ๊ฒ์ฆ์ด ์๋ํ๋ ค๋ฉด ํ์ํ ์กฐ๊ฑด
| ์กฐ๊ฑด | ์ค๋ช |
| @Valid | DTO์ ๋ถ์ด์ ํด๋น ๊ฐ์ฒด๋ฅผ ๊ฒ์ฆํ๋ผ๊ณ ์ง์ |
| BindingResult | ๊ฒ์ฆ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํจ. ์์ผ๋ฉด ์คํ๋ง์ด ์์ธ ํฐ๋จ๋ฆผ |
| spring-boot-starter-validation | ์ด ์์กด์ฑ์ด ์์ด์ผ ์ ์ฒด ๊ฒ์ฆ ๊ธฐ๋ฅ์ด ์๋ํจ (Gradle์ ํฌํจ๋์ด ์์ด์ผ ํจ) |
์ฃผ์์ฌํญ ์ ๋ฆฌ
- @Valid ๋ค์๋ ๋ฌด์กฐ๊ฑด BindingResult ๋ถ์ด์ผ ํจ -> ์๊ทธ๋ฌ๋ฉด ์๋ฌ๋จ
- ๋ฐ์ธ๋ฉ์ด ์ ๋๋ ํ์ (์: age์ ๋ฌธ์๊ฐ ๋ค์ด์ฌ ๊ฒฝ์ฐ)์ @Valid์ ์ฉ ์์ฒด๊ฐ ์๋จ-> BindingResult์ ์๋ฌ๋ก๋ง ๋จ์
- DTOํ๋๋ง๋ค ์ด๋ ธํ ์ด์ ์ ๊ผญ ์จ์ค์ผ ๊ฒ์ฆ์ด ์ ์ฉ๋จ
ํต์ฌ ๋ฌธ๋ฒ ์ ๋ฆฌ
1) ์์กด์ฑ ์ถ๊ฐ(build.gradle)
implementation 'org.springframework.boot:spring-boot-starter-validation'
2) DTO์์ ๊ฒ์ฆ ์ด๋ ธํ ์ด์ ์ฌ์ฉํ๊ธฐ
@Getter
public class SignUpRequestDto{
@NotBlank(massage="์ด๋ฆ์ ํ์์
๋๋ค.") //null, ""," " ๋ถ๊ฐ๋ฅ
private String name;
@NotNull(message="๋์ด๋ ํ์์
๋๋ค.")//null ๋ถ๊ฐ๋ฅ
@Range(min=1, max=120, message="๋์ด๋ 1~120 ์ฌ์ด์ฌ์ผ ํฉ๋๋ค.");
private Integer age;
}
- ๋ฌธ์์ด์ด๋ฉด @NotBlank
- ์ซ์๋ฉด @NotNull
- ๋ฒ์์ ํ @Range
3) Controller์์ ๊ฒ์ฆ์ฒ๋ฆฌ ๋ฌธ๋ฒ
@PostMapping("/signup")
public String signup{
@Valid SignUpRequestDto dto, // 1. ๊ฒ์ฆํ DTO
BindingResult bindingResult, // 2. ๊ฒ์ฆ ๊ฒฐ๊ณผ ์ ์ฅ (์์ ์ค์!)
Model model // 3. Thymeleaf์ ๋ฐ์ดํฐ ๋๊ธฐ๊ธฐ
) {
if(bindingResult.hasError){
//์๋ฌ ์์ผ๋ฉด ์ฌ๊ธฐ์ ์ฒ๋ฆฌ
return "error";
}
//์ ์์ฒ๋ฆฌ
model.addAttribute("name",dto.getName());
model.addAttribute("age",dto.getAge());
}
}
'Backend > ๐ฑ Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Spring]Filter (0) | 2025.07.29 |
|---|---|
| [Spring] filter์ค์ต๊น์ง ์งํํ ํ ์ดํดํ ๋ด์ฉ ์ ๋ฆฌ (1) | 2025.07.29 |
| [Spring]์์กด๊ด๊ณ ์ฃผ์ (DI) (2) | 2025.07.28 |
| [Spring]Spring Bean (2) | 2025.07.28 |
| [Spring] Layered Architecture (3) | 2025.07.26 |