열심히 끝까지

디바이스 융합 자바(Java) day93 - Spring Boot : Validator(유효성 검사) 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day93 - Spring Boot : Validator(유효성 검사)

노유림 2022. 10. 26. 11:42

> 면접 때 답해볼 수 있는 사항
[Spring Boot] 기법 
[Validator]
>> 유효성 검사
      : 사용자가 보낸 데이터(form)에 대한 유효성 검사
         ex ) 로그인, 회원가입(form), url, 등...
      : 이 유효성 검사는 "두 단계"로 진행하는 것이 보편적임
            1. 클라이언트(브라우저, 사용자) 측에서 검사 : JS로 검사
            2. 서버 : 파라미터 값을 검증
                      => 회사마다 많이 다름
                      => 유지보수에 불리함
                -> 스프링 부트에서는 Validator 인터페이스를 구현해 놓음
                -> 개발자들이 보다 일관된 코드를 작성할 수 있게 됨

@Override
public void validate(Object target, Errors errors) { // 유효성 검사 객체
		
}

  > 상대가 쓴 코드중에 인자로 Object로 작성되어 있으면
  > 보통 뭐가 올지 몰라서 작성된 상황
  > Object target : 사용자의 입력 값(커맨트 객체)을 검증하기 위해, 파라미터로 받을 수 있게 구현한 부분
                 -> 디자인 패턴을 활용

 

-------------------------

if(writer.isEmpty() || writer==null) {

}

 

 - writer의 메모리가 진짜 없는 상황이면 isEmpty조차 수행할 수 없기 때문에
   null부터 작성해주어야 함

---------------------------

if(writer==null || writer.trim().isEmpty()) { // ★ null 체크 순서 유의!!

}

- 사이 띄우기 혹은 엔터값을 없애주는 .trim() 작성하면 더 정확하게 유효성 검사 가능

 

Q. errors 객체에 에러 내용을 저장했는데, 별도의 return을 하지 않음
A. .validate()를 수행할 때에, errors 객체를 "참조변수"로 활용하기 때문!!
                                                          -> 모델 객체

 

insertPage.jsp--------------------------

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>작성 페이지</title>
</head>
<body>
<%
	String contextPath=request.getContextPath();
%>

<form action="/insert" method="post">
	작성자 : <input type="text" name="writer" value="${dto.writer}"><br>
	내용 : <input type="text" name="content" value="${dto.content}"><br>
	<input type="submit" value="글 작성하기">
</form> 

</body>
</html>

boardPage.jsp--------------------------

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>상세 페이지</title>
</head>
<body>

${dto.writer} | ${dto.content}

</body>
</html>

DataDTO.java--------------------------

package com.ryo.springboot;

public class DataDTO {
	private int id;
	private String writer;
	private String content;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	@Override
	public String toString() {
		return "DataDTO [id=" + id + ", writer=" + writer + ", content=" + content + "]";
	}
	
}

DataValidator.java---------------------

package com.ryo.springboot;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class DataValidator implements Validator{

	@Override
	public boolean supports(Class<?> clazz) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void validate(Object target, Errors errors) {
		// 상대가 쓴 코드중에 인자로 Object로 작성되어 있으면
		// 보통 뭐가 올지 몰라서 작성된 상황
		// Object target : 사용자의 입력 값(커맨트 객체)을 검증하기 위해, 파라미터로 받을 수 있게 구현한 부분
		// -> 디자인 패턴을 활용한 예 : 부모에게 자시긍ㄹ 대입 가능

		DataDTO dto = (DataDTO)target;

		// 커맨드 객체에 저장된 값을 추출
		String writer = dto.getWriter();
//		if(writer.isEmpty() || writer==null) {
//			writer의 메모리가 진짜 없는 상황이면 isEmpty조차 수행할 수 없기 때문에
//			null부터 작성해주어야 함
//		}
		if(writer==null || writer.trim().isEmpty()) { // ★ null 체크 순서 유의!!
			System.out.println("로그 : DataValidator: validate 메서드 : 작성자 null or empty");
			errors.rejectValue("writer", "error");
		}
		String content = dto.getContent();
		if(content==null || content.trim().isEmpty()) {
			System.out.println("로그 : DataValidator: validate 메서드 : 내용 null or empty");
			errors.rejectValue("content", "error");
		}

	} // 유효성 검사 객체

}

TestController.java---------------------

package com.ryo.springboot;

import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class TestController {
	
	@RequestMapping("/")
	public @ResponseBody String root() {
		return "Validator 실습";
	}
	
	@RequestMapping("/insertPage")
	public String insertPage() {
		return "insertPage";
	}
	
	@RequestMapping("/insert")
	public String insert(@ModelAttribute("dto")DataDTO dto,BindingResult result) {
		// 돌아가게 되면 데이터가 유지되도록 @ModelAttribute("dto")에 저장하도록 지시
		String viewName="boardPage";
		
		System.out.println("로그 : TestController : insert 메서드 : dto : "+dto);
		DataValidator validator = new DataValidator();
		// 유효성 검사 객체 생성
		validator.validate(dto, result);
		// result는 ★"참조변수"이기 때문에(실제 데이터가 존재하기 때문에)
		// error 페이지의 반환이 없어도 사용 가능하다!
		
		if(result.hasErrors()) { // null값이 있다면, 에러가 발견되었다면(result가 에러 갖고 있어?)
			viewName = "insertPage";
		}

		return viewName;
	}
}

실행 결과---------------------------------

content가 null일 경우-----------------

content가 차 있지만 writer가 null일 경우-----------------

content, writer 둘 다 잘 들어가 있는 경우----------------