본문 바로가기
Programming/>> Spring

[Spring] Spring Validator

by 니키ᕕ( ᐛ )ᕗ 2015. 12. 2.

validator, validate는 입력받은 값이 유효한지를 검사하는 것이다. 

주로 회원가입 입력 폼 같은 곳에서 지정된 문자열의 길이나 정규표현식이 일치하는지 확인하는 데에 쓰인다.



이 화면은 github의 회원가입 화면인데, 자바스크립트와 ajax를 이용해서 validate를 진행한다.

순수하게 자바스크립트를 이용해서 validate를 구현할 수 있지만 Spring에서 지원하니 써보기도 해야되고 무엇보다.. 

회사에서 서비스사 유지보수 작업할 때 자바스크립트로만 validate를 했다가 스팸봇한테 개털린 기억이 있어서 가능하면 서버단에서 진행하는게 안전하다고 생각한다.



context.xml에 추가할 bean은 없지만, Validator 인터페이스를 구현한다. 

구현에 앞서 message.properties와 Vo로 사용할 TbUser클래스를 준비. (TbUser는 Hibernate 설정할 때 생성한 것이다.)


- message_ko.properties
join.userid.length=This id is too long or short.
join.userid.regex=This id should be a valid(alphabet + number(0~9)).
join.userid.duplicate=This id is already used. Enter other id.
join.password.length=Choose your password from minimum 8 to maximum 15 characters.
join.password.regex=This password should be a valid(alphabet + number(0~9)).
join.name.length=This name is too long or short(maximum 20 characters).
join.email.regex=This email should be a valid.
join.gender.empty=Select your gender.
join.interests=Interests
join.interests.empty=Check your interests at least one.


validator에서 사용할 문구를 설정한다. 직접 메소드에 입력해도 되지만 유지보수의 편의성 및 다국어 처리를 위해 properties파일을 사용한다. 

정확한 내용은 이전 포스팅 참고 [Java] Spring 다국어 지원 


- JSP

<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%> <div id="content"> <form:form id="member_join_form" commandName="tbUser"> ..... <form:errors path="userid" /> <div class="form-group"> <label for="userid"><spring:message code="join.userid"/></label> <input type="text" class="form-control" name="userid" value="${tbUser.userid}"> </div> ..... </form:form> </div>

유효성 검사를 진행할 Form을 구성하는데, 우선 Spring이 form태그를 사용할 수 있도록 form taglib를 import한 뒤 <form:form> 내부에 요소들을 추가한다.

그리고나서 form의 attribute에 회원가입 과정에 쓰일 Vo 클래스와 동일한(앞 글자는 소문자로) 이름을 넣는다. 

내가 사용한 클래스 이름은 TbUser이고, Controller에서 model atrribute를 user로 넘겼는데 제대로 작동을 하지 않았다. 이름을 일치시켜주는게 중요한듯 하다.


<form:errors path="userid" />은 userid에 대해 유효성 검사를 했을 때, 에러가 나면 메세지를 표시하는 부분이다. 

화면에선 span태그 안에 생성되며 태그를 바꾸려면 <form:errors path="userid" element="태그"/>로 하면 되고 class를 지정하고 싶다면 <form:errors path="userid" cssClass="class이름"/>로 표시한다. 


해당 메세지가 아닌 부모 엘레멘트에 클래스를 추가하고 싶다면

<%@ taglib uri="http://www.springframework.org/tags" prefix="spring"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<div id="content">
   	<form:form id="member_join_form" commandName="tbUser">
		.....
		  <c:set var="erUserid"><form:errors path="userid" /></c:set>
		  <div class="form-group <c:if test="${not empty erUserid}">has-error</c:if>">
		    <label for="userid"><spring:message code="join.userid"/></label>
		    <input type="text" class="form-control" name="userid" value="${tbUser.userid}">
		    <c:if test="${not empty erUserid}"><span class="has-error-msg">${erUserid}</span></c:if>
		  </div>
		.....
	</form:form>
</div>

<c:set var="erUserid"><form:errors path="userid" /></c:set>와 같이 c태그를 이용하여 erUserid에 메세지를 저장하고, 

if문을 이용하여 erUserid에 값이 있다면 class를 추가한다.


- Validator

public class JoinValidator implements Validator {
	@Override
	public boolean supports(Class<?> clazz) {
		return TbUser.class.equals(clazz);
	}
	@Override
	public void validate(Object target, Errors errors) {
		TbUser user = (TbUser) target;
		// userid
		if (user.getUserid().length() < 4 || user.getUserid().length() > 15) {
			errors.rejectValue("userid", "join.userid.length");
		} 
	}
}

Validator 인터페이스를 구현한 JoinValidator 클래스를 만들었다.

support는 validate에 object로 넘어온 객체가 검증 가능한 객체인지 판단하고 validate는 본격적으로 유효성 검사를 진행한다. 

예제는 간단하게 userid의 문자열 길이가 최소 4 ~ 최대 15인지를 확인하고 join.userid.length의 메세지를 출력한다.



- Controller

@Controller
public class MemberController {
	....
	@RequestMapping(value="/join", method=RequestMethod.POST)
	public String doJoin(Model model, TbUser tbUser, BindingResult bindingResult){
		new JoinValidator().validate(tbUser, bindingResult);
		if(bindingResult.hasErrors()){
			model.addAttribute("tbUser", tbUser);
			return "/member/member_join";
		} else {
			// 데이터처리
			// redirect
			return "redirect:/";
		}
	}
}

JoinValidator를 new로 생성하여 tbUser와 bindingResult를 넘겨주면 유효성검사를 한다. 

유효성 검사 결과 에러유무를 판별하고 에러가 있다면 객체를 다시 화면에 뿌려주고 없다면 다음 과정으로 넘어간다.


BindingResult는 Form 값을 tbUser객체에 바인딩한 결과를 저장하고 에러 코드로부터 에러 메시지를 가져온다.



댓글