2-31 데이터의 변환과 검증(2)

서현우·2022년 5월 28일
0

복습

목록 보기
23/34

Validator란?

객체를 검증하기 위한 인터페이스. 객체 검증기(validator)구현에 사용

public interface Validator {
	//이 검증기로 검증가능한 객체인지 알려주는 메서드
	boolean supports(Class<?> clazz);
	//객체를 검증하는 메서드 - target: 검증할 객체, errors: 검증시 발생한 에러저장소
	void validate(@Nullable Object target, Errors errors);
}
public class UserValidator implements Validator {
	@Override
	public boolean supports(Class<?> clazz) {
		return User.class.isAssignableFrom(clazz); //clazz가 User 또는 그 자손인지 확인
	}
	@Override
	public void validate(Object target, Errors errors) {
		User user = (User)target;
		
		String id = user.getId();
		
		//if(id==null || "".equals(id.trim())) {
		//	errors.rejectValue("id", "required");
		//}
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "id", "required");
		ValidationUtils.rejectIfEmptyOrWhitespace(errors, "pwd", "required");
		
		if(id==null || id.length()<5 || id.length()>12) {
			errors.rejectValue("id", "invalidLength");
		}
	}
}

Errors의 메서드

public interface Errors {
	void reject(String errorCode); //객체 전체 에러 저장
	void rejectValue(String field, String errorCode); //필드 에러 저장

예전에는 컨트롤러 메서드에서 아래와 같이 작성

@PostMapping("/register/add")
public String save(Model model, User user, BindingResult result) {
	String msg = "";
	String id = user.getId();
	if(id==null||"".equals(id.trim())){
		model.addAttribute("msg", "id는 필수 입력항목입니다.");
		return "redirect:/register/add";
	
	if(id==null||id.length()<5 || id.length()>12) {
		model.addAttribute("msg", "id의 글자는 5글자이상 12글자 미만입니다.");
		return "redirect:/register/add";
	}
}

Validator를 사용해서 컨트롤러에 아래와 같이 작성

UserValidator userValidator = new UserValidator();
userValidator.validate(user, result); //validator로 검증

if(result.hasErrors()) { //에러가 있으면
	return "registerForm"; //jsp
}

Validator를 이용한 자동 검증

아래는 RegisterController내에서만 동작함.

@InitBinder
public void toDate(WebDataBinder binder) {
	SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
	binder.registerCustomEditor(Date.class, new CustomDateEditor(df, false));
	
	binder.setValidator(new UserValidator()); //validator를 WebDateBinder에 등록
	
	List<Validator> validators = binder.getValidators();
	System.out.println("validators="+validators);
}
@PostMapping("/register/add") //신규 회원 등록
public String save(Model m, @Valid User user, BindingResult result) {
	if(result.hasErrors()) { //에러가 있으면
		return "registerForm"; //jsp
	}

글로벌 Validator

하나의 Validator로 여러 객체를 검증할 때, 글로벌 Validator로 등록.
1. 글로벌 Validator로 등록 방법.
servlet-context.xml

<annotation-driven validator="globalValidator"/>
<beans:bean id="globalValidator" class="com.fastcampus.ch2.GlobalValidator"/>
  1. 글로벌 Validator와 로컬 Validator를 동시에 적용하는 방법
@InitBinder
public void toDate(WebDataBinder binder) {
	SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
	binder.registerCustomEditor(Date.class, new CustomDateEditor(df, false));
	
	binder.addValidators(new UserValidator()); //로컬 Validator를 WebDataBinder에 등록

MessageSource

다양한 리소스에서 메세지를 읽기 위한 인터페이스

public interface MessageSource {
	String getMessage(String code, Object[] args, String defaultMessage, Local locale);
	String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
	String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}

프로퍼티 파일을 메세지 소스로 하는 ResourceBundleMessageSource를 등록
servlet-context.xml

<beans:bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
	<beans:property name="basenames">
		<beans:list>
			<beans:value>error_message</beans:value>
		</beans:list>
	</beans:property>
	<beans:property name="defaultEncoding" value="UTF-8"/>
</beans:bean>

[error_message.properties]

required=필수 항목입니다.
required.user.pwd=사용자 비밀번호는 필수 항목입니다.
invalidLength.id=아이디의 길이는 {1}~{2}사이어야 합니다.

검증 메세지의 출력

스프링이 제공하는 커스텀 태그 라이브러리를 사용

<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
//<form>대신 <form:form>사용
<form:form modelAttribute="user">
==>
<form id="user" action="/ch2/register/save" method="post">
//<form:errors>로 에러를 출력. path에 에러 발생 필드를 지정
<form:errors path="id" cssClass="msg"/>
==>
<span id="id.errors" class="msg">필수 입력 항목입니다.</span>
profile
안녕하세요!!

0개의 댓글