본문 바로가기
프로그래밍/스프링프레임워크

전자정부표준프레임워크 폼 검증(Form validation)하기

by pentode 2018. 5. 2.

전자정부표준프레임워크는 폼 검증에 Jakarta Commons Validator를 사용하고, 이것을 Spring Framework와 연동하기 위해서 spring-modules-validation 을 사용합니다.

(https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:ptl:security:jakarta_commons_validator)


Jakarta Commons Validator는 각종 검증 규칙을 xml 파일로 작성합니다. 이 규칙에 따른 검증은 Java 클래스 및 Javascript로도 제공되어 서버측 검증과 클라이언트측 검증 모두에서 사용되어 집니다.


이글의 예제는 전자정부표준프레임워크의 eGovFrame Web Project에서 생성된 샘플 소스를 사용하여 테스트 해 봅니다.



1. 예제용 프로젝트 만들기

- 메뉴에서 "File -> New -> egovFrame Web Project"를 선택합니다.

- 다음 정보로 프로젝트를 생성합니다.(나머지는 기본값 사용)


Project name: egov_validation

Target Runtime: Apache Tomcat 8.0

Dynamic Web Module version: 2.5

Group Id: egov_validation


- Generate Example에 체크하여예제 코드를 만듭니다.



2. 전자정부표준프레임워크 샘플에는 기본적으로 Jakarta Commons Validator와 spring-modules-validation 라이브러리가 포함되어 있습니다.

- 전자정부표준프레임워크가 아니라 스프링프레임워크에 적용이 필요하다면 아래 의존성을 pom.xml 파일에 적용하면 추가하면 되겠습니다.


<dependency>

    <groupId>commons-validator</groupId>

    <artifactId>commons-validator</artifactId>

    <version>1.4</version>

</dependency>

<dependency>

    <groupId>org.springmodules</groupId>

    <artifactId>spring-modules-validation</artifactId>

    <version>0.9</version>

</dependency>



3. Validation기능 설정하기

- src/main/resources/egovframework/spring/context-validator.xml 파일에서 검증 기능을 수행하는 빈을 생성합니다.


<bean id="beanValidator" class="org.springmodules.validation.commons.DefaultBeanValidator">

    <property name="validatorFactory" ref="validatorFactory"/>

</bean>


<bean id="validatorFactory" class="org.springmodules.validation.commons.DefaultValidatorFactory">

    <property name="validationConfigLocations">

        <list>

            <value>/WEB-INF/config/egovframework/validator/validator-rules.xml</value>

            <value>/WEB-INF/config/egovframework/validator/validator.xml</value>

        </list>

    </property>

</bean>


- DefaultValidatorFactory는 사용되는 모든 규칙을 가지고 있는 validator-rules.xml 파일과 입력폼에서 규칙이 어떻게 적용되는지 정보를 가지고 있는 validator.xml 파일을 받아서 필요한 Commons Validator들의 인스턴스를 생성합니다.

- DefaultBeanValidator는 validatorFactory로 부터 가져온 인스턴스를 이용해서 실제 검증을 수행합니다.

- 폼별 검증 방법을 가지고 있는 validator.xml 파일은 폼별로 여러개로 나눠 만들 수 있습니다. 그럴경우 다음과 같이 지정할 수있습니다.(클래스패스 아래 여러개의 설정파일을 로드하도록 지정한 예입니다.)


<value>classpath:/egovframework/validator/validator-rules.xml</value>

<value>classpath:/egovframework/validator/**/*.xml</value>


4. validator-rules.xml 설정하기

- 이 파일을 사용되어질 수 있는 모든 검증 규칙을 정의해둔 파일 입니다. 아래는 필수값 체크 예입니다.


<validator name="required"

      classname="org.springmodules.validation.commons.FieldChecks"

         method="validateRequired"

   methodParams="java.lang.Object,

                 org.apache.commons.validator.ValidatorAction,

                 org.apache.commons.validator.Field,

                 org.springframework.validation.Errors"

             msg="errors.required">

    <javascript><![CDATA[

        function validateRequired(form) {

            ...

        }

    ]]>

    </javascript>

</validator>



4.1. <validator>의 속성

- name : 검증 규칙을 나타냅니다.

- classname : 검증을 수행하는 클래스명 입니다.

- method : classname으로 지정된 클래스에서 검증을 수행하는 메서드명 입니다.

- methodParams : 검증을 수행하는 메서드의 파라미터 입니다.

- msg : 에러 메세지의 key 값입니다.

- javascript : 클라이언트측 검증을 수행할 자바스크립트 입니다. method 속성에 지정된 것과 같은 함수명입니다.



4.2. 제공되는 검증 규칙

- FieldCheck 클래스 이름은 다음과 같습니다.

* springmodules : org.springmodules.validation.commons.FieldChecks

* egovframework : egovframework.rte.ptl.mvc.validation.RteFieldChecks


이름클래스메서드기능
requiredspringmodulesvalidateRequired필수값 체크
requiredifspringmodulesvalidateRequiredIf다른 필드의 값에 따른 체크
validwhenspringmodulesvalidateValidWhen다른 필드의 값에 따른 체크
minlengthspringmodulesvalidateMinLength최소 길이 체크
maxlengthspringmodulesvalidateMaxLength최대 길이 체크
maskspringmodulesvalidateMask정규식으로 체크
bytespringmodulesvalidateByte-128 <= 값 <= 128 체크
shortspringmodulesvalidateShort-32768 <= 값 <= 32767 체크
integerspringmodulesvalidateInteger-2147483648 <= 값 <= 2147483647 체크
longspringmodulesvalidateLongLong값 체크
floatspringmodulesvalidateFloatFloat값 체크
doublespringmodulesvalidateDoubleDouble값 체크
datespringmodulesvalidateDate날짜 체크
rangespringmodulesvalidateRange범위 체크
intRangespringmodulesvalidateIntRange정수범위 체크
floatRangespringmodulesvalidateFloatRange실수범위 체크
creditCardspringmodulesvalidateCreditCard신용카드번호 체크
emailspringmodulesvalidateEmail이메일 체크
ihidnumegovframeworkvalidateIhIdNum주민번호 체크
koreanegovframeworkvalidateKorean한글인지 체크
htmltagegovframeworkvalidateHtmlTagHTML태그인지 체크


- 검증에 사용되는 클래스와 메서드는 org.springmodules.validation.commons.FieldChecks와 이 클래스의 메서드들 입니다. 이 클래스는 내부적으로 Commons Validator 인스턴스를 사용하도록 되어 있습니다.

- Commons Validator는 계속 업데이트 되고 있는데, springmodules-validation은 개발이 중단된것 같습니다. Commons Validator에 추가된 기능을 사용하기 위해서는 springmodules의 FieldChecks 클래스를 상속해서 추가된 기능을 넣을 수 있습니다.

(https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:ptl:validation:add_rules_in_commons_validator)



5. validator.xml 설정하기

- validator.xml 파일은 검증할 폼의 필드들과 검증 규칙을 연결하는 정보를 가지는 파일 입니다.


<form name="sampleVO">

    <field property="name" depends="required">

        <arg0 key="title.sample.name" />

    </field>

    <field property="description" depends="required">

        <arg0 key="title.sample.description" />

    </field>

    <field property="regUser" depends="required">

        <arg0 key="title.sample.regUser" />

    </field>

</form>



5.1. <form> 태그의 name 속성


- validator.xml 파일 안의 form name 은 HTML의 <form> 태그의 name 속성과 관계가 없습니다.

- 서버측 검증은 컨트롤러에서 submit된 값이 맵핑되는 클래스 이름이 됩니다.(SampleVO sampleVO)

- 클라이언트측 검증은 jsp 파일의 <valdator:javascript> 태그의 formName 속성의 값이 됩니다.


// 컨트롤러 java 파일

@RequestMapping(value = "/addSample.do", method = RequestMethod.POST)

public String addSample(SampleVO sampleVO, BindingResult bindingResult, Model model) throws Exception {

    // Server-Side Validation

    beanValidator.validate(sampleVO, bindingResult);


// jsp 파일

<validator:javascript formName="sampleVO" staticJavascript="false" xhtml="true" cdata="false"/>


- 그러므로 validator.xml의 <form name="sampleVO"> 속성, 컨트롤러의 메소드 public String addSample(SampleVO sampleVO), jsp의 <validator:javascript formName="sampleVO"/> 태그의 formName 속성

세 가지를 일치시켜야 서버측과 클라이언트측의 검증이 모두 동작합니다.



5.2. <field> 태그

- peroperty 속성은 폼 데이터가 맵핑되는 클래스의 이름과, HTML 폼의 엘리먼트의 이름과 같습니다.

- depnds 속성은 validator-rules.xml에 정의되어 있는 적용될 규칙을 지정합니다. 여러개의 규칙을 지정하기 위해서는 콤마(,)로 분리하여 여러개를 지정할 수 있습니다.



5.3 <arg0> 태그

- 필드에 대한 라벨에 해당하는 내용을 지정합니다. 메세지 프로퍼티의 키를 지정할 수 도 있고 직접 값을 입력할 수도 있습니다.

- 예로 <arg0 key="이름"/>로 지정되어 있는 필수 입력필드에 입력하지 않으면, "이름은 필수 입력입니다." 라는 에러메세지가 보여지게 됩니다.



6. 서버측 검증

6.1. 컨트롤러 (Controller)에서 검증하기

- 서버측 검증은 주로 컨트롤러에서 하게 됩니다.


@Controller

public class EgovSampleController {

    /** Validator */

    @Resource(name = "beanValidator")

    protected DefaultBeanValidator beanValidator;

    @RequestMapping(value = "/addSample.do", method = RequestMethod.POST)

    public String addSample(SampleVO sampleVO, BindingResult bindingResult, Model model) throws Exception {


    // 서버측 검증

    beanValidator.validate(sampleVO, bindingResult);


    if(bindingResult.hasErrors()) {

        model.addAttribute("sampleVO", sampleVO);

        return "sample/egovSampleRegister";

    }

    ...

}


- context-validator.xml에서 정의한 beanValidator가 검증에 사용되어집니다.


beanValidator.validate(samplevO, bindingResult);


- 검증 결과는 bindingResult 객체에 저장되어 집니다. 에러가 있으면 다시 입력페이지를 보여줍니다.


if(bindingResult.hasErrors()) {}



6.2. 검증 결과를 JSP페이지에 보여주기


<tr>

    <td class="tbtd_caption"><label for="name"><spring:message code="title.sample.name" /></label></td>

    <td class="tbtd_content">

    <form:input path="name" maxlength="30" cssClass="txt"/>

    &nbsp;<form:errors path="name" /></td>

</tr>


- 스프링 <form:errors> 태그로 오류 메세지가 보여지게 됩니다.



6.3. 에러메세지 등록하기

- 에러 메세지는 src/main/resources/egovframework/message/message-common.properties 파일에 등록합니다. 다국어 메세지 프로퍼티 파일 입니다.


errors.required={0} 은 필수 입력값입니다.

errors.minlength={0} 은 {1}자 이상 입력해야 합니다.

errors.maxlength={0} 은 {1}자 이상 입력할수 없습니다.


6.4. 실행결과 입니다.



7. 클라이언트측 검증


7.1. validator.jsp 추가하기

- src/main/webapp/WEB-INF/jsp/egovframework/example/cmmn/validator.jsp 파일 입니다.


<%@ page language="java" contentType="javascript/x-javascript" %>

<%@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" %>

<validator:javascript dynamicJavascript="false" staticJavascript="true"/>


- 이 파일은 validator-rules.xml 파일에 있는 모든 자바스크립트 함수를 모아둔 .js 파일과 같이 동작합니다.

- /validator.do 파일로 맵핑하는 컨트롤러를 만들어도 되고, 이 예제에서는 <mvc:view-controller>를 이용한 정적 맵핑을 사용합니다.

- src/main/webapp/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml 파일입니다.


<mvc:view-controller path="/cmmn/validator.do" view-name="cmmn/validator"/>


7.2. jsp 파일에 taglib 및 javascrip 추가하기


- src/main/webapp/WEB-INF/jsp/egovframework/example/sample/egovSampleRegister.jsp 파일입니다.


<!-- valitor-rules.xml 파일의 모든 자바스크립트 라이브러리 입니다. -->

<script type="text/javascript" src="<c:url value='/cmmn/validator.do'/>"></script>


<!-- validator.xml의 sampleVO 를 검증하기위한 스크립트를 생성합니다. -->

<validator:javascript formName="sampleVO" staticJavascript="false" xhtml="true" cdata="false"/>


<script type="text/javaScript" language="javascript" defer="defer">

<!--

/* 글 등록 function - 등록시 검증을 수행합니다. */

function fn_egov_save() {

    frm = document.detailForm;

    if(!validateSampleVO(frm)) {

        return;

    } else {

        frm.action = "<c:url value="${registerFlag == 'create' ? '/addSample.do' : '/updateSample.do'}"/>";

        frm.submit();

    }

}

-->

</script>


7.3 클라이언트측 검증 실행 결과 입니다.



반응형