일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 예약
- 외부키
- querydsl
- 컨테이너실행
- 추후정리
- subquery
- ubuntu
- MySQL
- 참조키
- 메소드명
- 메세지수정
- 테스트
- 적용우선순위
- foreignkey
- WeNews
- appspec
- AuthenticationEntryPoint
- EC2
- 커밋메세지수정
- 테스트메소드
- docker명령어
- application.yml
- appspec.yml
- 검색
- 2 > /dev/null
- Query
- 네이티브쿼리
- 서브쿼리
- 포트
- ㅔㄴ션
- Today
- Total
제뉴어리의 모든것
DTO 값 검증 처리 방법 본문
Spring Boot 프로젝트에서 DTO 검증 방법
- 환경
OS : Windows10
IDE : Intellij 2020.03
Spring Boot : 2.4.5
- 프로젝트 구조
- Dependency
implementation 'org.webjars:jquery:3.1.1-1'
//@Valid, @Size, @NotEmpty 등등 현재 예제에서 소개하는 검증에 대한 디펜던시
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
- 예제 프로젝트 흐름도
- 구현
1. 기본 패키지에 controller, dto 패키지 추가
2. controller 패키지에 HomeController, MemberController Java 클래스 생성
package com.january.dto_valid.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
@Controller
public class HomeController {
@GetMapping("/")
public String home(@ModelAttribute("result") String result)
{
return "index";
}
}
package com.january.dto_valid.controller;
import com.january.dto_valid.dto.MemberDTO;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;
@RequestMapping("/member")
@Controller
public class MemberController {
@GetMapping("/register")
public String register(@ModelAttribute("memberDTO") MemberDTO memberDTO)
{
return "/member/register";
}
@PostMapping("/register")
public String register(@Valid MemberDTO memberDTO,
Errors errors, RedirectAttributes redirectAttributes, Model model){
if(errors.hasErrors())
{
//기존 데이터 그대로
model.addAttribute("memberDTO", memberDTO);
// 유효성 통과 못한 필드와 메시지를 핸들링
Map<String, String> validatorResult = validateHandling(errors);
for (String key : validatorResult.keySet()) {
model.addAttribute(key, validatorResult.get(key));
}
return "/member/register";
}
redirectAttributes.addAttribute("result", "valid value!");
return "redirect:/";
}
public Map<String, String> validateHandling(Errors errors) {
Map<String, String> validatorResult = new HashMap<>();
for(FieldError error : errors.getFieldErrors())
{
String fieldName = String.format("valid_%s",error.getField());
validatorResult.put(fieldName,error.getDefaultMessage());
}
return validatorResult;
}
}
위에 소스에서 주요한 내용은
public String register(@Valid MemberDTO memberDTO,
Errors errors, RedirectAttributes redirectAttributes, Model model)
입니다.
- @Valid :
검증할 DTO에 @Valid 라는 어노테이션을 달아주었습니다. 해당 어노테이션을 달아주어야
DTO 클래스에서 검증을 적용한 변수에 대하여 검증을 실시합니다.
- Errors :
Errors 라는 타입의 변수를 Controller 메소드의 파라미터로 정의 해주어야 검증과정에서 발생된 에러에 대하여 알 수있습니다.
그리고 아래의 내용은
회원가입 페이지에서 입력받은 내용을 그래도 다시 Model에 담아서 <input> 에 출력해주려는 의도입니다.그리고 validateHandling 라는 메소드에서는 각 필드(input 항목)에 대한 에러 메세지를 Map형태로 반환해줍니다.그리고 각 key,value를 Model 객체에 넣어서 View로 전달해 줍니다.
if(errors.hasErrors())
{
//기존 데이터 그대로
model.addAttribute("memberDTO", memberDTO);
// 유효성 통과 못한 필드와 메시지를 핸들링
Map<String, String> validatorResult = validateHandling(errors);
for (String key : validatorResult.keySet()) {
model.addAttribute(key, validatorResult.get(key));
}
return "/member/register";
}
3. dto 패키지에 MemberDTO Java 클래스 생성
package com.january.dto_valid.dto;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
@Setter
@Getter
public class MemberDTO {
@Size(min = 2, max = 20)
@NotEmpty(message = "id는 빈값 일 수 없습니다")
@NotNull(message = "id는 Null 일 수 없습니다")
private String id;
@Size(min = 8, max = 12)
@NotEmpty(message = "비밀번호는 빈값 일 수 없습니다")
@NotNull(message = "비밀번호는 Null 일 수 없습니다")
private String password;
@Size(min = 2, max = 8)
@NotEmpty(message = "이름은 빈값 일 수 없습니다")
@NotNull(message = "이름은 Null 일 수 없습니다")
private String name;
@Email
@Size(min = 12, max = 20)
@NotEmpty(message = "이메일은 빈값 일 수 없습니다")
@NotNull(message = "이메일은 Null 일 수 없습니다")
private String email;
}
@Size : 최소, 최대 길이에 대하여 정의를합니다
@NotEmpty : ""와 같이 빈값이 되어선 안됨을 의미합니다
@NotNull : Null을 허용하지 않음을 의미합니다.
@Email : Email형식으로 입력 받아야함을 나타냅니다.
각 어노테이션마다의 message는 검증에 실패하였을때 발생되는 Error 메세지입니다.
4. /template/member 패키지에 register.html와 /template에 웰컴페이지(index.html) 생성
register.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<form th:action="@{/member/register}" method="post">
<div>
<label>ID : </label>
<input type="text" name="id" th:value="${memberDTO.id}">
<span th:text="${valid_id}" style="color: red"></span>
</div>
<div>
<label>PWD : </label>
<input type="text" name="password" th:value="${memberDTO.password}">
<span th:text="${valid_password}" style="color: red"></span>
</div>
<div>
<label>NAME : </label>
<input type="text" name="name" th:value="${memberDTO.name}">
<span th:text="${valid_name}" style="color: red"></span>
</div>
<div>
<label>EMAIL : </label>
<input type="text" name="email" th:value="${memberDTO.email}">
<span th:text="${valid_email}" style="color: red"></span>
</div>
<button type="submit"> 등록 </button>
</form>
</body>
</html>
위 소스에서 주요할점은
<input type="text" name="id" th:value="${memberDTO.id}">와 같이 ${memberDTO.id}값이존재하다면
value로써 정의해주었으므로, 잘못된 값을 입력하여 본 페이지로 다시 돌아왔을때 입력하였던 값을 그대로 다시 input에 출력해 줍니다.
그리고
<span th:text="${valid_id}" style="color: red"></span> 와 같이 ${valid_id} 란 값을 span을 이용하여 나타냅니다.
당연히 최초 가입 페이지 입장시에는 ${valid_id}란 값은 존재하지 않기때문에 아무런 텍스트도 출력되지 않습니다.
index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<script th:src="@{/webjars/jquery/3.1.1-1/jquery.min.js}"></script>
<title>index</title>
</head>
<body>
<h2>웰컴 페이지</h2>
<a th:href="@{/member/register}">
<h1>가입하기</h1>
</a>
<script th:inline="javascript">
$(document).ready(function () {
const result = [[${result}]];
if(result != "")
{
alert(result);
}
})
</script>
</body>
</html>
가입 페이지에서 각 input들이 모두 검증에 통과되었을때
[[${result}]] 의 값이 넘어오기 때문에 alert창을 띄우고 성공했음을 알립니다.
- 결과
- 웰컴 페이지 입장
- 가입 페이지 입장
- 아무런 값도 입력하지 않고 등록버튼 클릭시
- 유효한 값 입력 상황
- 유효한 값 입력 후 등록 버튼 클릭시
github url : unool/dto_valid (github.com)
'Spring Boot' 카테고리의 다른 글
object references an unsaved transient instance - save the transient instance before flushing 에러 (1) | 2022.09.03 |
---|---|
DTO 유효성 검사시 주의 사항 (@NotBlank, @NotEmpty, @NotNull에 대하여) - 매우 중요 (0) | 2022.08.28 |
favicon.ico 와 AuthenticationEntryPoint .. (0) | 2021.04.12 |
@Builder.Default (0) | 2021.04.09 |
ResponseEntity<>와 ajax 사용시 주의사항 (0) | 2021.04.08 |