: 스프링은 객체가 유효한지의 여부를 검사할 때 사용되는 Validator 인터페이스와 유효성 검사 결과를 저장할 Erros 인터페이스를 제공하고 있다. 스프링 MVC도 Validator 인터페이스를 이용해서 폼 값을 저장한 Dto 객체의 유효성 여부를 검사하고, 입력한 값이 유효하지 않은 경우 Errors에 에러 메시지를 저장해서 뷰에 전달하게 된다.
먼저 Validator 인터페이스를 구현한 커스텀 Validator를 간단히 작성해보자.
==== GameValidator.java ====
package egovframework.rte.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import egovframework.rte.dto.GameDto;
public class GameValidator implements Validator
{
@Override
public boolean supports(Class<?> clazz)
{
return GameDto.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors)
{
GameDto gameDto = (GameDto)target;
if(gameDto.getOpenFlag() == null || gameDto.getOpenFlag().trim().isEmpty())
{
errors.rejectValue("openFlag", "errors.required.radio", new String[]{"공개여부"},"");
}
if(gameDto.getPassNo() == null || gameDto.getPassNo().trim().isEmpty())
{
errors.rejectValue("passNo", "errors.required.text", new String[]{"비밀번호"},"");
}
if(gameDto.getGameTitle() == null || gameDto.getGameTitle().trim().isEmpty())
{
errors.rejectValue("gameTitle", "errors.required.text", new String[]{"제목"},"");
}
if(gameDto.getGameDesc() == null || gameDto.getGameDesc().trim().isEmpty())
{
errors.rejectValue("gameDesc", "errors.required.text", new String[]{"게임설명"},"");
}
if(gameDto.getBasicInfo() == null || gameDto.getBasicInfo().trim().isEmpty())
{
errors.rejectValue("basicInfo", "errors.required.text", new String[]{"기본정보"},"");
}
}
}
--> 해당 필드가 유효성 검사에서 걸리게 되면 rejectValue() 메서드를 호출해서 에러 정보를 저장한다. 위에서는 필드가 null 이거나 공백일 경우만 체크하고 있다.
--> rejectValue() 메서드는 rejectValue(체크할 프로퍼티명, 에러코드(메시지 프로퍼티파일의 키값), 에러 메시지에 삽입될 인자 목록, 디폴트 메시지) 형식이다. 매개변수의 타입은 API를 참조하자.
--> 에러메시지에 삽입될 인자목록은 해당 메시지가 "{0}은 디폴트로 입력해야됩니다."라고 메시지 프로퍼티 파일에 정의되어있다면 {0}에 인자목록의 첫번째 값이 매칭된다.
위의 null 및 공백 체크는 ValidationUtils 클래스의 메서드를 이용해서 아래와 같이 간단하게 수정할 수 있다.
==== GameValidator.java ====
package egovframework.rte.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import egovframework.rte.dto.GameDto;
public class GameValidator implements Validator
{
@Override
public boolean supports(Class<?> clazz)
{
return GameDto.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object target, Errors errors)
{
ValidationUtils.rejectIfEmpty(errors, "openFlag", "errors.required.radio", new String[]{"공개여부"});
ValidationUtils.rejectIfEmpty(errors, "passNo", "errors.required.text", new String[]{"비밀번호"});
ValidationUtils.rejectIfEmpty(errors, "gameTitle", "errors.required.text", new String[]{"제목"});
ValidationUtils.rejectIfEmpty(errors, "gameDesc", "errors.required.text", new String[]{"게임설명"});
ValidationUtils.rejectIfEmpty(errors, "basicInfo", "errors.required.text", new String[]{"기본정보"});
}
}
다음으로 요청을 받는 컨트롤러쪽의 코드이다.
==== GameController.java ===
/**
* 게임 등록 처리
*
*/
@RequestMapping(value="gameReg", method=RequestMethod.POST)
public String gameDictReg(@ModelAttribute("game")GameDto gameDto, BindingResult result) throws Exception
{
logger.info(gameDto.toString());
new GameValidator().validate(gameDto, result);
if(result.hasErrors())
{
return "game/gameRegForm";
}
//gameService.insertDataGame(gameDto);
return "redirect:/onnuri/game/questionRegForm?gameSeq=" + gameDto.getGameSeq() + "&gameType=" + gameDto.getGameType();
}
--> Errors 인터페이스를 상속받은 BindingResult 인터페이스의 result 에 에러가 존재하면 폼으로 다시 리다이렉트 시킨다.
다음으로 메시지 프로퍼티 파일에 대한 설정을 해보자. 스프링 설정 파일에 아래 빈을 등록한다.
==== dispatcher-servlet.xml ====
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="egovframework.message.message-validator"/>
--> BindingResult 인터페이스의 기본 구현 클래스인 AbstractBindingResult 클래스는 MessageCodesResolver를 사용하여 에러 코드에 대한 에러 메시지를 추출하는데, 기본적으로 DefaultMessageCodesResolver 클래스를 MessageCodesResolver로 사용한다. 이 DefaultMessageCodeResolver는 MessageSource로 부터 에러코드에 해당하는 메시지를 로딩한다. 따라서 DefaultMessageCodesResolver를 이용하여 에러 메시지를 생성하려면 위와같이 알맞는 MessageSource를 빈으로 등록해 주어야 한다.
--> basenames 프로퍼티에는 프로퍼티 파일명을 패키지 경로명까지 입력해주면 된다. 위에서는 egovframework.message까지가 패키지명이고, message-validator가 message-validator.properties 파일의 이름이다.
==== message-validator.properties ====
# -- validator errors -- #
errors.required.text = {0} 은(는) 필수 입력값입니다.
errors.required.radio = {0} 을(를) 선택 하셔야 합니다.
errors.minlength={0} 은 {1}자 이상 입력해야 합니다.
errors.maxlength={0} 은 {1}자 이상 입력할수 없습니다.
errors.invalid={0} 은 유효하지 않은 값입니다.
마지막으로 등록 폼인 뷰페이지를 작성해보자.
==== gameRegForm.jsp ====
<%@ 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="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<c:import url="/include/header.jsp"/>
<form:form name="gameRegForm" action="/onnuri/game/gameReg" commandName="game" method="POST">
이메일: <form:input path="userEmail" title="이메일" cssClass="email required" maxlength="30" readOnly="readOnly"/><br/><br/>
공개여부: <form:radiobutton path="openFlag" value="Y" label="공개" title="공개여부" cssClass="required"/> <form:radiobutton path="openFlag" value="N" label="비공개" title="공개여부" cssClass="required"/>
<form:errors path="openFlag"/><br/><br/>
비밀번호: <form:password path="passNo" title="비밀번호" cssClass="password required" maxlength="15"/> [4-6자의 영문/숫자 혼용으로 입력해주세요.]
<form:errors path="passNo"/><br/><br/>
<!-- 게임유형: <form:radiobuttons items="${gameTypeList}" path="gameType" title="게임유형" cssClass="required"/><br/><br/>-->
게임제목: <form:input path="gameTitle" title="게임제목" cssClass="required" maxlength="50"/>
<form:errors path="gameTitle"/><br/><br/>
게임설명: <form:textarea path="gameDesc" cols="50" rows="3" title="게임설명" cssClass="required"/>
<form:errors path="gameDesc"/><br/><br/>
기본정보: <form:textarea path="basicInfo" cols="50" rows="3" title="기본정보" cssClass="required"/>
<form:errors path="basicInfo"/><br/><br/>
<input type="button" id="btnReg" value="다음단계"/>
</form:form>
<c:import url="/include/footer.jsp"></c:import>
<script type="text/xxjavascript" src="/js/game/game.js"></script>
--> 유효성 검증에서 에러가 발생했을때 위 태그로 설정한 부분에 에러메시지가 표시된다.
자세하게 설명을 하고 싶지만 몸이 좀 좋질 않아서... ㅡㅡㅋ