✅ 검증 (Validator)
✅ 검증을 하는 이유
✅ BindingResult
✅ 스프링부트 Validator 적용
Maven Repository 에서 Hibernate Validator Engine
검색
스프링 부트가 spring-boot-starter-validation
라이브러리를 넣으면 자동으로
Bean Validator를 인지하고 스프링에서 통합
✅ 적용 원리
LocalValidatorFactoryBean
을 글로벌 Validator로 등록한다
이 Validator은 필드 위에 적는 @NotNull
, @Size
등의 어노테이션을 보고 검증을 수행한다
이렇게 글로벌 Validator이 적용되어 있기 때문에, @Valid
, @Validated
만 적용하면 됨
Valid
-> 자바 표준 전용 검증 애노테이션
Validated
-> 스프링 전용 검증 애노테이션
검증 오류가 발생하면 FieldError
, ObjectError
을 생성해서 BindingResult
에 담아줌
6버전까지 -> javax
그 이후부터는 -> jakarta
jakarta를 사용하려면
-> 스프링 프레임워크 6버전 이상
-> 톰캣 10버전 이상
-> jdk 17이상
-> 스프링부트 3.0이상
등록과 수정을 groups
를 이용해서 validation 처리하면 복잡도가 올라가서 실무에서 잘 사용 x
-> 등록, 수정용 폼 객체를 나누면 완전히 분리되기 때문에, groups
를 적용할 일은 드물다
등록과 수정 나눈 소스코드 확인 -> https://velog.io/@choi-ju-yung/%EB%93%B1%EB%A1%9D-%EC%88%98%EC%A0%95-validation-%EA%B5%AC%EB%B6%84
✅ pom.xml 파일에 spring-boot-starter-validation
넣기
# pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
✅ 객체 클래스 만들기
NotNull
-> null만 허용하고 공백은 가능함@NotEmpty
-> null, 공백 둘다 허용 x@NotBlank
-> null, 공백, 띄어쓰기 모두 허용 x@Size
-> min,max를 통해 최소,최대 사이즈를 지정가능@Min @Max
-> @Size와 동일@Email
-> 이메일 형식이 아닌 경우 예외 발생message
속성을통해 예외 메시지 처리가능// 회원가입 등록 클래스 객체
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class MemberDto {
@NotEmpty(message = "아이디는 반드시 입력하세요!")
@Size(min=4, message = "아이디는 최소 4글자 이상 입력하세요") // 최소 4글자
private String user_Id;
@Pattern(regexp = "(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[~!@#$%^&*()])[a-zA-Z~!@#$%^&*()]{8,}"
, message = "영소문자, 대문자, 특수기호를 포함하고 8글자 이상 작성")
private String password;
@NotEmpty
private String name;
@Min(value=15,message = "15살이상 입력")@Max(value = 150,message = "150이하 입력")
private int age;
@Email
private String email;
@NotEmpty
private String phone;
private String address;
private String hobby;
private Date enroll_Date;
}
✅ MemberController
1. 회원가입 화면으로 이동하기전에 view에서 매칭할 ModelAttribute
값을 동일하게 설정해야함
2. view에서 회원가입 폼 전송하면, 받는 컨트롤러 쪽에서 @Validated
의 값을 동일하게 설정해야함
3. 검증오류 발생시 BindingResult
객체에 자동으로 담아줌
4. BindingResult
객체에 검증오류가 있으면 -> hasErrors
메소드 -> 다시 회원가입 입력창으로 이동
@Controller
@RequestMapping("/member")
public class MemberController {
private MemberService service;
public MemberController(MemberService service) {
this.service = service;
}
@GetMapping("/insertMember")
public String intsertMemberView(@ModelAttribute("memberDto") MemberDto m) {
// @ModelAttribute값은 회원가입페이지 view에서 <springform:form> 태그의 modelAttribute 값과 동일해야함
return "member/insertMember";
}
@PostMapping("/insertMember.do")
public String insertMember(@Validated MemberDto m, BindingResult isResult, Model model){
if(isResult.hasErrors()) {
return "member/insertMember";
}else {
System.out.println("문제 x");
return "member/insertMember";
}
}
}
✅ 회원가입 뷰 jsp 화면
<%@ taglib prefix="springform" uri="http://www.springframework.org/tags/form"%>
생성<springform:form>
태그를 이용해서 검증 실시modelAttribute
설정<springform:erros>
및 path
추가path
-> 자바 객체의 필드와 동일하게 작성<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="springform" uri="http://www.springframework.org/tags/form"%>
<c:set var="path" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<style>
.error{
color:red;
font-weight: bolder;
margin-bottom: 10px;
width: 1000px;
}
.row{
display:flex;
flex-direction: column;
width: 300px;
}
#user_Id_{
margin-bottom: 10px;
}
</style>
<body>
<h2>회원가입</h2>
<springform:form modelAttribute="memberDto" name="memberEnrollFrm" action="${path}/member/insertMember.do" method="post">
<div class="row">
<springform:input path="user_Id" type="text" placeholder="아이디(4글자이상)" name="user_Id" id="user_Id_"/>
<springform:errors path="user_Id" cssClass="error"/>
<springform:input path="password" type="password" placeholder="비밀번호" name="password" id="password_"/>
<springform:errors path="password" cssClass="error"/>
<input type="password" placeholder="비밀번호확인" name="password2" id="password2_">
<springform:input path="name" type="text" placeholder="이름" name="name" id="name_"/>
<springform:errors path="name" cssClass="error"/>
<springform:input path="age" type="number" placeholder="나이" name="age" id="age_"/>
<springform:errors path="age" cssClass="error"/>
<springform:input path="email" type="email" placeholder="이메일" name="email" id="email_"/>
<springform:errors path="email" cssClass="error"/>
<springform:input path="phone" type="tel" placeholder="전화번호" name="phone" id="phone_"/>
<springform:errors path="email" cssClass="error"/>
<springform:input path="address" type="text" placeholder="주소" name="address" id="address_"/>
<springform:errors path="email" cssClass="error"/>
<springform:input path="hobby" type="text" placeholder="취미" name="hobby" id="hobby_"/>
<springform:errors path="email" cssClass="error"/>
<input type="submit" value="가입">
</div>
</springform:form>
</body>
</html>