스프링부트 Validator 적용

최주영·2024년 2월 27일
0

springboot

목록 보기
11/14

✅ 검증 (Validator)

  • 클라이언트 검증 (JS에서 검증) -> 보안에 취약
  • 서버 검증 -> 즉각적인 고객 사용성이 부족
  • 두개를 적절히 섞어서 사용해야함, 최종적으로 서버 검증은 필수

✅ 검증을 하는 이유

  • 폼 입력시 검증 오류가 발생하면 오류화면으로 바로 이동하게 되는 것을 막기 위해서

✅ 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 추가
    -> 각 입력태그마다 <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>
profile
우측 상단 햇님모양 클릭하셔서 무조건 야간모드로 봐주세요!!

0개의 댓글