스프링 검증(Spring Validation)은 사용자 입력값에 대한 유효성 검사를 구현하기 위한 기능이다.
순서
1. validation-api 라이브러리를 프로젝트에 빌드 처리 - 메이븐 : pom.xml
2. HTML 태그 대신 Spring 태그를 사용하여 페이지 요청시 입력값이 전달되도록 뷰 작성
3. Controller 클래스의 요청 처리 메소드에서 전달값이 저장된 Command 객체를 저장하는 매개변수에 @Valid 어노테이션을 사용하여 Command 객체를 생성하는 VO 클래스에서 유효성 검증이 되도록 설정
DTO 클래스
@Data
public class Employee {
//@NotNull : 전달값이 [null]인 경우 에러를 발생하는 어노테이션
//@NotBlank : 전달값이 [null]이거나 전달값에 공백이 있는 경우 에러를 발생하는 어노테이션
//@NotEmpty : 전달값이 [null]이거나 [""] 경우 에러를 발생하는 어노테이션
// => 에러 발생시 기본적인 메세지를 제공받아 뷰에게 전달
//message 속성 : 뷰에게 전달할 에러 메세지를 속성값으로 설정
@NotEmpty(message = "아이디를 입력해 주세요.")
//@Size : 전달값의 크기를 비교하여 에러를 발생하는 어노테이션
//min 속성 : 전달값의 최소 크기를 속성값으로 설정
//max 속성 : 전달값의 최대 크기를 속성값으로 설정
//@Size(min = 6, max = 20, message = "아이디는 최소 6자 이상 최대 20자 이하로만 입력해 주세요.")
//@Pattern : 정규표현식의 패턴과 같지 않은 경우 에러를 발생하는 어노테이션
//regexp 속성 : 전달값의 패턴을 비교하기 위한 정규표현식을 속성값으로 설정
@Pattern(regexp = "^[a-zA-Z]\\w{5,19}$", message = "아이디를 형식에 맞게 입력해 주세요.")
private String id;
@NotEmpty(message = "비밀번호를 입력해 주세요.")
@Pattern(regexp = "^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[~!@#$%^&*_-]).{6,20}$", message = "비밀번호를 형식에 맞게 입력해 주세요.")
private String passwd;
@NotEmpty(message = "이름을 입력해 주세요.")
private String name;
@NotEmpty(message = "이메일을 입력해 주세요.")
//@Email : 이메일 형식이 틀린 경우 에러를 발생하는 어노테이션
@Email(message = "이메일을 형식에 맞게 입력해 주세요.")
private String email;
@NotEmpty(message = "성별을 입력해 주세요.")
private String gender;
}
1. validation-api 라이브러리를 프로젝트에 빌드 처리
https://mvnrepository.com/artifact/javax.validation/validation-api/2.0.1.Final
https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator/6.2.5.Final

2. HTML 태그 대신 Spring 태그를 사용하여 페이지 요청시 입력값이 전달되도록 뷰 작성
html_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%-- JavaScript(jQuery)를 이용하여 사용자 입력값의 검증 - 클라이언트 --%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<style type="text/css">
.error {
color: red;
}
</style>
</head>
<body>
<h1>사원등록</h1>
<hr>
<c:url value="/valid/html" var="url"/>
<form action="${url}" method="post" id="joinForm">
<table>
<tr>
<td>아이디</td>
<td>
<input type="text" name="id" id="id" value="${employee.id }">
<span id="idMsg" class="error">${idMsg }</span>
</td>
</tr>
<tr>
<td>비밀번호</td>
<td>
<input type="password" name="passwd" id="passwd">
<span id="passwdMsg" class="error"></span>
</td>
</tr>
<tr>
<td>이름</td>
<td>
<input type="text" name="name" id="name">
<span id="nameMsg" class="error"></span>
</td>
</tr>
<tr>
<td>이메일</td>
<td>
<input type="text" name="email" id="email">
<span id="emailMsg" class="error"></span>
</td>
</tr>
<tr>
<td>성별</td>
<td>
남자<input type="radio" name="gender" value="남자" class="gender">
여자<input type="radio" name="gender" value="여자" class="gender">
<span id="genderMsg" class="error"></span>
</td>
</tr>
<tr>
<td colspan="2">
<button type="submit">등록</button>
</td>
</tr>
</table>
</form>
<script type="text/javascript">
$("#joinForm").submit(function() {
var submitResult=true;
$(".error").hide();
/*
var idReg=/^[a-zA-Z]\w{5,19}$/g;
if($("#id").val()=="") {
$("#idMsg").html("아이디를 입력해 주세요.");
submitResult=false;
} else if(!idReg.test($("#id").val())) {
$("#idMsg").html("아이디를 형식에 맞게 입력해 주세요.").show();
submitResult=false;
}
*/
var passwdReg=/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[~!@#$%^&*_-]).{6,20}$/g;
if($("#passwd").val()=="") {
$("#passwdMsg").html("비밀번호를 입력해 주세요.");
submitResult=false;
} else if(!passwdReg.test($("#passwd").val())) {
$("#passwdMsg").html("비밀번호를 형식에 맞게 입력해 주세요.");
submitResult=false;
}
if($("#name").val()=="") {
$("#nameMsg").html("이름을 입력해 주세요.");
submitResult=false;
}
var emailReg=/^([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+(\.[-a-zA-Z0-9]+)+)*$/g;
if($("#email").val()=="") {
$("#emailMsg").html("이메일을 입력해 주세요.");
submitResult=false;
} else if(!emailReg.test($("#email").val())) {
$("#emailMsg").html("이메일을 형식에 맞게 입력해 주세요.");
submitResult=false;
}
if($(".gender").filter(":checked").length == 0) {
$("#genderMsg").html("성별을 선택해 주세요.");
submitResult=false;
}
$(".error").show();
return submitResult;
});
</script>
</body>
</html>
spring_form.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%-- Spring 프레임워크에서 제공하는 폼태그 라이브러리 포함 --%>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
<style type="text/css">
.error {
color: red;
}
</style>
</head>
<body>
<h1>사원등록</h1>
<hr>
<c:url value="/valid/spring" var="url"/>
<%-- Spring Form 태그 : 페이지를 요청하여 입력값을 전달하는 태그 --%>
<%-- modelAttribute 속성(필수) : 요청 처리 메소드 매개변수에 저장된 Command 객체의 속성명을 속성값으로 설정 --%>
<%-- => 유효성 검증 실패시 사용자 입력값이 저장된 Command 객체를 제공받아 사용 --%>
<form:form action="${url }" method="post" modelAttribute="employee">
<table>
<tr>
<td>아이디</td>
<td>
<%-- Spring input 태그 : 문자열을 입력받기 위한 태그 --%>
<%-- => input 태그의 type 속성값을 [text]로 설정하는 것과 동일 --%>
<%-- path 속성 : 값을 전달하기 위한 이름을 속성값으로 설정 --%>
<%-- => input 태그의 name 속성값과 id 속성값을 동시에 설정하는 것과 동일 --%>
<%-- => 유효성 검증이 실패하는 경우 value 속성값을 설정하는 것과 동일 --%>
<form:input path="id"/>
<%-- Spring errors 태그 : 에러메세지를 제공받아 출력하는 태그 --%>
<%-- path 속성 : 에러메세지를 제공받아 출력하기 위한 식별자(전달값의 이름)를 속성값으로 설정 --%>
<%-- cssClass 속성 : 에러메세지를 출력하기 위한 CSS 스타일의 클래스 선택자를 속성값으로 설정 --%>
<%-- element 속성 : 에러메세지를 출력하기 위한 태그를 속성값으로 설정 --%>
<%-- delimiter 속성 : 에러메세지가 여러개인 경우 구분하기 위한 구분자를 속성값으로 설정 - 기본 구분자 : <br> --%>
<form:errors path="id" cssClass="error" element="span" delimiter=" "/>
</td>
</tr>
<tr>
<td>비밀번호</td>
<td>
<%-- Spring password 태그 : 문자열을 입력받기 위한 태그 --%>
<%-- => input 태그의 type 속성값을 [password]로 설정하는 것과 동일 --%>
<form:password path="passwd"/>
<form:errors path="passwd" cssClass="error" element="span" delimiter=" "/>
</td>
</tr>
<tr>
<td>이름</td>
<td>
<form:input path="name"/>
<form:errors path="name" cssClass="error" element="span" delimiter=" "/>
</td>
</tr>
<tr>
<td>이메일</td>
<td>
<form:input path="email"/>
<form:errors path="email" cssClass="error" element="span" delimiter=" "/>
</td>
</tr>
<tr>
<td>성별</td>
<td>
<%-- Spring radiobutton 태그 : 목록 중 하나를 선택하여 전달하기 위한 태그 --%>
<%-- => input 태그의 type 속성값을 [radio]로 설정하는 것과 동일 --%>
<%--
남자<form:radiobutton path="gender" class="gender" value="남자"/>
여자<form:radiobutton path="gender" class="gender" value="여자"/>
--%>
<%-- Spring radiobuttons 태그 : 목록 중 하나를 선택하여 전달하기 위한 태그 --%>
<%-- => List 객체의 요소값을 제공받아 선택 가능 목록 제공 --%>
<%-- items 속성 : List 객체(EL)를 속성값으로 설정 --%>
<%-- <form:radiobuttons path="gender" items="${genderList }"/> --%>
<%-- Spring select 태그 : 목록 중 하나를 선택하여 전달하기 위한 태그 --%>
<%-- => select 태그와 option 태그를 설정하는 것과 동일 --%>
<form:select path="gender" items="${genderList }"/>
<form:errors path="gender" cssClass="error" element="span" delimiter=" "/>
</td>
</tr>
<tr>
<td colspan="2">
<%-- Spring button 태그 : 제출 이벤트를 발생하기 위한 태그 --%>
<%-- => button 태그의 type 속성값을 [submit]로 설정하는 것과 동일 --%>
<form:button>등록</form:button>
</td>
</tr>
</table>
</form:form>
<%--
<script type="text/javascript">
$("#joinForm").submit(function() {
var submitResult=true;
$(".error").hide();
var idReg=/^[a-zA-Z]\w{5,19}$/g;
if($("#id").val()=="") {
$("#idMsg").html("아이디를 입력해 주세요.");
submitResult=false;
} else if(!idReg.test($("#id").val())) {
$("#idMsg").html("아이디를 형식에 맞게 입력해 주세요.").show();
submitResult=false;
}
var passwdReg=/^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[~!@#$%^&*_-]).{6,20}$/g;
if($("#passwd").val()=="") {
$("#passwdMsg").html("비밀번호를 입력해 주세요.");
submitResult=false;
} else if(!passwdReg.test($("#passwd").val())) {
$("#passwdMsg").html("비밀번호를 형식에 맞게 입력해 주세요.");
submitResult=false;
}
if($("#name").val()=="") {
$("#nameMsg").html("이름을 입력해 주세요.");
submitResult=false;
}
var emailReg=/^([a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+(\.[-a-zA-Z0-9]+)+)*$/g;
if($("#email").val()=="") {
$("#emailMsg").html("이메일을 입력해 주세요.");
submitResult=false;
} else if(!emailReg.test($("#email").val())) {
$("#emailMsg").html("이메일을 형식에 맞게 입력해 주세요.");
submitResult=false;
}
if($(".gender").filter(":checked").length == 0) {
$("#genderMsg").html("성별을 선택해 주세요.");
submitResult=false;
}
$(".error").show();
return submitResult;
});
--%>
</body>
</html>
result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>SPRING</title>
</head>
<body>
<h1>사원정보확인</h1>
<hr>
<ul>
<li>아이디 = ${employee.id }</li>
<li>비밀번호 = ${employee.passwd }</li>
<li>이름 = ${employee.name }</li>
<li>이메일 = ${employee.email }</li>
<li>성별 = ${employee.gender }</li>
</ul>
</body>
</html>
3. Controller 클래스의 요청 처리 메소드에서 전달값이 저장된 Command 객체를 저장하는 매개변수에 @Valid 어노테이션을 사용하여 Command 객체를 생성하는 VO 클래스에서 유효성 검증이 되도록 설정
컨트롤러
package xyz.itwill10.controller;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import javax.validation.Valid;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import xyz.itwill10.dto.Employee;
//스프링 검증(Spring Validation) : 사용자 입력값에 대한 유효성 검사를 구현하기 위한 기능
//1.validation-api 라이브러리를 프로젝트에 빌드 처리 - 메이븐 : pom.xml
//2.HTML 태그 대신 Spring 태그를 사용하여 페이지 요청시 입력값이 전달되도록 뷰 작성
//3.Controller 클래스의 요청 처리 메소드에서 전달값이 저장된 Command 객체를 저장하는 매개변수에
//@Valid 어노테이션을 사용하여 Command 객체를 생성하는 VO 클래스에서 유효성 검증이 되도록 설정
@Controller
@RequestMapping("/valid")
public class ValidController {
@RequestMapping(value = "/html", method = RequestMethod.GET)
public String html() {
return "valid/html_form";
}
@RequestMapping(value = "/html", method = RequestMethod.POST)
public String html(@ModelAttribute Employee employee, Model model) {
//전달값에 대한 입력값 검증 - 서버
if(employee.getId() == null || employee.getId().equals("")) {
model.addAttribute("idMsg", "아이디를 입력해 주세요.");
return "valid/html_form";
}
String idReg="^[a-zA-Z]\\w{5,19}$";
if(!Pattern.matches(idReg, employee.getId())) {
model.addAttribute("idMsg", "아이디를 형식에 맞게 입력해 주세요.");
return "valid/html_form";
}
employee.setPasswd(BCrypt.hashpw(employee.getPasswd(), BCrypt.gensalt()));
return "valid/result";
}
//Spring Form 태그에서 사용하기 위한 Command 객체를 저장할 매개변수 선언
@RequestMapping(value = "/spring", method = RequestMethod.GET)
public String spring(@ModelAttribute Employee employee) {
//List 객체를 생성하여 뷰에게 제공
//model.addAttribute("genderList", Arrays.asList("남자", "여자"));
return "valid/spring_form";
}
//@Valid : Spring 태그에 의해 전달된 값을 Command 객체의 필드에 저장하기 전에 전달값에
//대한 유효성 검증 기능을 제공하기 위한 어노테이션
// => VO(DTO) 클래스의 필드에 유효성 검증 관련 어노테이션 사용 - hibernate-validator
//라이브러리를 프로젝트에 빌드 처리 - 메이븐 : pom.xml
//Errors 객체 : 유효성 검증 후 발생되는 모든 에러 관련 정보를 저장하기 위한 객체
@RequestMapping(value = "/spring", method = RequestMethod.POST)
public String spring(@ModelAttribute @Valid Employee employee, Errors errors) {
//Errors.hasErrors() : Errors 객체에 에러 관련 정보가 존재할 경우 [true]를 반환하는 메소드
if(errors.hasErrors()) {
//model.addAttribute("genderList", Arrays.asList("남자", "여자"));
return "valid/spring_form";
}
employee.setPasswd(BCrypt.hashpw(employee.getPasswd(), BCrypt.gensalt()));
return "valid/result";
}
//모든 요청 처리 메소드의 뷰에게 반환값을 제공하는 어노테이션
@ModelAttribute("genderList")
public List<String> genderList() {
return Arrays.asList("남자", "여자");
}
}
'학원 > 복기' 카테고리의 다른 글
[Spring] Spring Security 로그인 커스터마이징 (0) | 2023.09.07 |
---|---|
[Spring] Spring Security (0) | 2023.09.06 |
[Spring] @RestController - 수정 (0) | 2023.08.19 |
[Spring] RESTful API (0) | 2023.08.19 |
[Spring] 자료실 만들기 (0) | 2023.08.15 |