Spring/Boot

[Boot] Validation

hvoon 2022. 9. 10. 20:48

Validation: null, 빈 값인지 검증하는 Annotation

 

src\main\java\com\ecl\g06\

package com.ecl.g06;

import lombok.Data;

@Data
public class ContentDto {
	private String writer;
	private String content;
}
package com.ecl.g06;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ValidController {

	@RequestMapping("/")
    public String main() {
    	return "startPage";       
    }
}
 

src\main\webapp\WEB-INF\views\startPage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>startPage.jsp</title>
</head>
<body>
<form action="create">
	작성자 : <input type="text" name="writer" value="${dto.writer}"> <br />
	내용 : <input type="text" name="content" value="${dto.content}"> <br />
	<input type="submit" value="전송"> <br />
	${message }
</form>
</body>
</html>
 

 

src\main\java\com\ecl\g06\

package com.ecl.g06;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class ValidController {

	@RequestMapping("/")
    public String main() {
    	return "startPage";       
    }
	
	@RequestMapping("/create")
	// startPage.jsp에서 form action="create"
	public String create( 
			@ModelAttribute("dto") ContentDto contentdto, Model model) {
		// 전송된 값들을 검사해서 한 개의 값이라도 비어 있으면 startPage.jsp로 되돌아감
		// 이 때 전송된 값을 저장하고 있는 contentdto 객체는
		//  dto란 이름으로 model에 담겨져서 이동
		
		// validation 기능이 있는 클래스를 생성하고 그 객체를 이용해서 검사함
		// 클래스의 이름은 ContentValidator, 
		// java의 Validator 인터페이스를 implements 한 클래스
		ContentValidator valid = new ContentValidator();
	}
}
package com.ecl.g06;

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

public class ContentValidator implements Validator{

	@Override
	public boolean supports(Class<?> clazz) { // 거의 사용할 일 없음
		return false;
	}
	@Override
	public void validate(Object target, Errors errors) {
		// Object target: 검사할 객체를 받아주는 매개변수(Object형).
		//                     전달된 객체 내의 멤버변수가 비어있는지 검사 예정
		// Errors errors: 보내온 객체에 에러내용을 담아서 
	}
}
package com.ecl.g06;

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

@Controller
public class ValidController {

	@RequestMapping("/")
    public String main() {
    	return "startPage";       
    }
	
	@RequestMapping("/create")
	// startPage.jsp에서 form action="create"
	public String create( 
			@ModelAttribute("dto") ContentDto contentdto, Model model,
			BindingResult result) {
		ContentValidator valid = new ContentValidator();
		valid.validate(contentdto, result);
		// BindingResult result: 에러 제목(키 값)과 내용(밸류값)을 담을 수 있는 객체
		// validator의 멤버메서드인 validate가 contentdto 내용을 검사한 후
		// result에 오류 내용을 담아주고 리턴되지 않아도 call by reference이기 때문에 
		// 오류 내용을 현재 위치에서도 result라는 이름으로 사용 가능함
		if (result.hasErrors()) {
			model.addAttribute("message","writer와 content는 비어 있으면 안됨");
    		return "startPage";
		}else { 
			return "DonePage";
		}
	}
}
package com.ecl.g06;

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

public class ContentValidator implements Validator{

	@Override
	public boolean supports(Class<?> clazz) {
		return false;
	}
	@Override
	public void validate(Object target, Errors errors) {
		ContentDto dto = (ContentDto)target;
		String sWriter = dto.getWriter();
		String sContent = dto.getContent();
		
		// null(new String()조차도 실행 안된것)이거나 값이 비어있거나("")
		if (sWriter==null || sWriter.trim().isEmpty()) {
			System.out.println("Writer is null or empty");
			errors.rejectValue("writer", "trouble");
		}
		if (sContent==null || sContent.trim().isEmpty()) {
			System.out.println("Content is null or empty");
			errors.rejectValue("content", "trouble");
		}
	}
}
 

src\main\webapp\WEB-INF\views\DonePage.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DonePage.jsp</title>
</head>
<body>
	<h1>startPage.jsp에서 DonePage.jsp로 전달된 내용</h1>
	<h1>이름: ${dto.writer }</h1>
	<h1>내용: ${dto.content }</h1>
</body>
</html>

 

 

전달 객체의 멤버 변수를 꺼내어 보지 않고 null이거나 비어 있는지 점검

(ValidationUtils.rejectIfEmptyOrWhitespace)

package com.ecl.g07;

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

public class ContentValidator implements Validator{

	@Override
	public boolean supports(Class<?> clazz) {
		return false;
	}
	
	@Override
	public void validate(Object target, Errors errors) {
		ContentDto dto = (ContentDto)target;
		// 전달 객체의 멤버 변수를 꺼내어 보지 않고 null이거나 비어 있는지 점검
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "writer", "writer is empty.");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "content", "content is empty.");
		// 전달된 특정 멤버변수의 글자수 점검
		String sWriter = dto.getWriter();
		if (sWriter.length() < 3) {
			errors.rejectValue("writer", "writer is too short.");
		}
	}
}
package com.ecl.g07;

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

@Controller
public class ValidController {

	@RequestMapping("/")
    public String main() {
    	return "startPage";       
    }
	
	@RequestMapping("/create")
	public String create( 
			@ModelAttribute("dto") ContentDto contentdto, Model model,
			BindingResult result) {
		ContentValidator valid = new ContentValidator();
		valid.validate(contentdto, result);
		if (result.hasErrors()) {
			if(result.getFieldError("writer")!=null)
				model.addAttribute("message","writer를 써주세요");
			else
				model.addAttribute("message","content를 써주세요");
    		return "startPage";
		}else { 
			return "DonePage";
		}
	}
}
아무것도 입력하지 않고 전송할 시

 

Validation 이용하기

 

package com.ecl.g08;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.Data;

@Data
public class ContentDto {
	@NotNull(message="Writer is Null")
	@NotEmpty(message="Writer is Empty")
	@Size(min=4, max=20,  message="writer min 4, max 20.")
	private String writer;
	@NotNull (message="Content is Null")
	@NotEmpty (message="Content is Empty")
	private String content;
	
	private String name;
}
package com.ecl.g08;

import javax.validation.Valid;

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

@Controller
public class ValidController {

	@RequestMapping("/")
	 public String root() throws Exception{
		 return "startPage";      
	 }
	
	@RequestMapping("/create")
	 public String create( 
			 @ModelAttribute("dto") @Valid ContentDto contentDto ,	 
			 BindingResult result , Model model) {
		String page = "DonePage";
		
		if(result.hasErrors()) {  // 어느 멤버변수인지 모르지만, 에러내용이 존재한다면
			page = "startPage";
			if( result.getFieldError("writer") != null) {
				//model.addAttribute("message", "writer 가 비어 있거나 3글자 미만이면 안됩니다.");
				model.addAttribute("message", result.getFieldError("writer").getDefaultMessage());
			} else if(result.getFieldError("content") != null) { 
				model.addAttribute("message", result.getFieldError("content").getDefaultMessage());
			}
		} else {
			
		}
		return page;
	}
}