Struts2에서 validator을 사용하는 3가지 방법.

1) Developer logic에 의한 검증방식
2) Annotation 방식으로 검증하는 방법
3) xml 방식으로 검증하는 방법

 Developer logic에 의한 방식은 개발자가 직접 business logic을 작성하여 사용하는 방법이다. 그러나 직접 작성한 방법은 검증받지 않았기 위험하다. 그래서 주로 api를 이용하는 방법인 Annotation이나 xml 방식으로 검증하는 방법을 사용한다.

1. Developer Logic에 의한 검증방식

Client(id, pw 를 보낸다) - 생략... -> Action --> Error --> <actionError>, <fieldError> --> Client


 action class에서 에러가 발생하게 되면 actionerror나 fielderror을 선택해서 에러를 보내준다. 그림에서 보듯이 success 들어오면 result.jsp 페이지로 이동하고 input 이나 error가 들어오면 다시 register.jsp 페이지로 돌아가는것을 확인 할 수 있다.

■ 작업 순서

jsp 페이지 만들기 -> Action.java 만들기 -> 랩퍼문서(validator.xml)만들기 -> struts.xml  만들기

이런 작업 순서로 하였고, WebContent의 index.jsp에서 접근하기 위한 경로를 입력한다.

1) jsp 페이지 만들기

<%@ page contentType="text/html;charset=euc-kr"%>
<%@ taglib prefix="s" uri="/struts-tags"%><!-- struts-tags를 사용한다 -->
<html>
  <body>
    <center><br><br>
    <h3><b>Struts2 Validator (register)</b></h3>
    <!-- 
              액션이름을  다음과 같이 설정한다.
              개발자 검증 : register.action
              어노테이션 검증 : annotation.action
    XML 검증 : xml.action 
    -->
    <form method="post" name="regform" action="register.action">
     <table border=0 cellpadding=0 cellspacing=1 bgcolor="#000000">
       <tr height=30 bgcolor="#ffffff">
         <td align="left" colspan=2>
           <span style="font-size:10pt; color:red">
              <s:fielderror/><!-- 원하는 곳에다 지정해서 에러를 보여 줄 수 있다 -->
           </span> 
         </td>
       </tr>
       <tr height=30 bgcolor="#ffffff">
         <td width=100 align="right"><b>성명</b>&nbsp;</td>
         <td width=300 align="left">&nbsp;
            <input type="text" name="name" value="${name }">
<!--            <s:fielderror name="name"/>-->
         </td>
       </tr>
 ................. 생략 ............................................................

<s:fielderror/> : 에러 태그를 한번에 다 보여준다.
<s:fielderror name="name"/> : name으로 설정된 property 에러만 출력한다.
 
두 태그를 원하는 곳에다가 입력하면 그 곳에 에러가 표시된다.

2) action class 만들기

/**
 * 개발자가 직접 작성한 로직에 의해 폼 검증을 수행하는 방식
 * 수행방법)
 *  1) 각  프로퍼티를 이용하여 유효한 값 인지 로직을 구현한다.
 *  2) 유효하지 않는 프로퍼티가 존재하면 다음과 같이 메소드를 호출한다.
 *   this.addFieldError("필드명", "전달할 메시지")
 *  3) execute() 메소드에서 다음과 같이 리절트 값을 리턴한다.
 *   . success : 성공시
 *   . input & error : 실패시
 */

package com.myhome.validator.actions;

import com.opensymphony.xwork2.ActionSupport;

@SuppressWarnings("serial")
public class DeveloperRegisterAction extends ActionSupport{//action 인터페이스를 사용해야 인터셉터 설정 할  수 있다.!!!! 우선 ActionSupport로..

 private String name;
 private int age;
 private String email;
 
 
 @Override
 public String execute() throws Exception{
  if(!this.isValidators()) return ERROR;
  return SUCCESS;
 }
 
 //검증코드 : 재사용성을 위해 이렇게 만든다.
 //로직을 만들고 메세지 주입 그리고  위(if(!this.isValidators()) return ERROR;)에서 수행
 protected boolean isValidators(){
  boolean flag = true;
  if(!this.isNameInvalid()){
   this.addFieldError("name", "이름을 다시 입력하세요");
   flag = false;
  }
  if(!this.isAgeInvalid()){
   this.addFieldError("age", "등록할 수 없는 나이입니다.");
   flag = false;
  }
  if(!this.isEmailInvalid()){
   this.addFieldError("email", "메일형식이 맞지 않습니다.");
   flag = false;
  }
  return flag;
 }

 //이름 검증부분
 //2자 이상인지 검증한다.
 protected boolean isNameInvalid(){
  if(name == null) return false;
  if(name.length() < 2) return false;
  return true;
 }
 
 //나이를 검증한다.
 //나이는 20~80세 까지만 허용한다.
 protected boolean isAgeInvalid(){
  if(age < 20 || age > 80) return false;
  return true;
 }
 
 //이메일을 검증한다.
 protected boolean isEmailInvalid(){
  if(email == null) return false;
  int idx = email.indexOf('@');
  if(idx == -1) return false;
  return true;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public String getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }
}

3) 랩퍼문서 만들기(validator.xml)

<?xml version="1.0" encoding="euc-kr"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
 <!-- name 이 중복되면 안된다.  -->
    <package name="validator" namespace="/validator" extends="struts-default">
     <action name="index">
      <result>/WEB-INF/validator/register.jsp</result>
     </action>
     
     <action name="xml"
       class="com.myhome.validator.actions.XMLRegisterAction"
       method="execute">
     
<!--  반드시 name이 있어야 하며, action에서 설정한 세개가 와야한다.-->
    
<result name="success">/WEB-INF/validator/result.jsp</result>      
     <result name="input">/WEB-INF/validator/register.jsp</result>
     <result name="error">/WEB-INF/validator/register.jsp</result>
     </action>
 
    </package>
   
</struts>

<result name="" 에서 input이 있으면 error 가 없어도 된다. 여기서는 action class에서 error를 설정해 놓아기 때문에 여기서는 꼭 설정한 세개가 다 와야 한다.

4) struts.xml 추가 한다.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <!-- include files -->
   <include file="validator.xml"/>
</struts>

2. Annotation 방식으로 검증하는 방법

(Developer Logic 설정에서)Action Class 만들기 --> validator.xml 수정 --> jsp 페이지 에서 action 설정

1) actino class 만들기

/**
 *  어노테이션 방식으로 폼 검증 방식
 *  사용방식)
 *  1) 현재 액션 클래스에서 어노테이션을 수행한다고 주석달기를 선언한다.
 *   @Validtion
 *   public class ...{}
 *  
 *  2) 검증할 getter 메소드 위에서 해당된 어노테이션을 설정한다. //getter에서만 사용.
 *   @RequiredFieldValidator(message="메세지")
 *   public String getName(){..."
 */

package com.myhome.validator.actions;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.validator.annotations.Validation;
import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
import com.opensymphony.xwork2.validator.annotations.StringLengthFieldValidator;
import com.opensymphony.xwork2.validator.annotations.IntRangeFieldValidator;
import com.opensymphony.xwork2.validator.annotations.EmailValidator;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;

@SuppressWarnings("serial")
@Validation
public class AnnotationRegisterAction extends ActionSupport{

 private String name;
 private int age;
 private String email;
 
 @Override
 public String execute() throws Exception{
  
  return SUCCESS;
 }
 
 @RequiredFieldValidator(message="이름은 필수 항목입니다.", type=ValidatorType.FIELD)//ValidatorType 정의. 이 type은 field 검색.
 @StringLengthFieldValidator(trim=true, minLength="2", message="존재하지 않는 이름입니다.")
 //@ExpressionValidator(expression="", message="한글만 가능합니다.")
public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 @IntRangeFieldValidator(min="20", max="80", message="등록할 수 없는 나이입니다.")
 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 @RequiredFieldValidator(message="메일을 입력하세요!!!")
 @EmailValidator(message="메일 형식이 맞지 않습니다.")//
여기다가 메세지를 주기 싫으면 메세지번들을 쓸 수 있는데 키를 가져다 쓴다.
 public String getEmail() {
  return email;
 }

 public void setEmail(String email) {
  this.email = email;
 }
 
}

2) validator.xml 수정

     
<action name="annotation"
                 class="com.myhome.validator.actions.AnnotationRegisterAction" 
                  method="execute">
      <result name="success">/WEB-INF/validator/result.jsp</result>
      <result name="input">/WEB-INF/validator/register.jsp</result>
      <result name="error">/WEB-INF/validator/register.jsp</result>
     </action>

3) jsp 페이지에서

 <form method="post" name="regform" action="annotation.action">
<!-- action 만 annotation.action을 지정하면 된다 -->

여러가지 기능을 지원하는 validation이 많기 때문에 api를 참조 한다.
com.opensymphoney.xwork2.validator.annotations

3. xml 방식으로 검증하는 방법

 
Container 들은 struts2가 가지고 이는 ActionSupport 에 의해서 액션을 호출하기 전에 먼저 xml 을 찾는다. 만약 xml 문서가 class 와 동일한 문서가 있으면, 먼저 xml 문서를 파라미터로 로딩하여 각각의 필드에 맞도록 수행하고 검증을 끝내면, exectue를 통해 다음 위치로 이동한다. 가장 중요한 것은 xml 문서를 만들 때, 클래스 명과 동일하게 명시해야 한다. 

 XMLRegisterAction.java 클래스를 만들었다면, 같은 위치에 XMLegisterAction-validation.xml 을 만들어야 한다. ex) 클래스이름-validation.xml 

이렇게 이름을 설정해야 Interceptor 들은 액션을 호출할 때 먼저 이 문서가 있는지 찾는다.

1) XMLRegisterAction.java 만들기

public class XMLRegisterAction extends ActionSupport{

 private String name;
 private int age;
 private String email;
 
............... 생략.....

class에서 설정한 property 들이 xml 에서 설정한 field-name과 일치해야 한다.

2) XMLRegisterAction-validation.xml 만들기

<?xml version="1.0" encoding="EUC-KR"?>
  <!DOCTYPE validators PUBLIC
     "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
   "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

   <validators>
        <field name="name">
          <!--문자가 널일 경우만 체크해준다.-->
    <field-validator type="requiredstring"><!-- requiredstring 정해져있는 타입 -->
        <param name="trim">true</param><!-- trim 공백 제거 -->
        <message>이름 입력오류!!!</message><!-- 보여줄 오류 메세지 -->
    </field-validator>
    <field-validator type="stringlength"><!-- 문자 길이 제한 -->
        <param name="minLength">2</param>
              <param name="trim">true</param>
              <message>이름은 최소 2자 이상 입력해야 합니다.</message>
          </field-validator>   
    </field>

       <field name="age">
            <field-validator type="int">  <!--정수를 체크할 때 사용된다.-->
        <param name="min">20</param>
        <param name="max">80</param>
        <message>금지된 나이오류!!!</message>
    </field-validator>
       </field>
        
       <field name="email">
          <field-validator type="email"><!--메일형식에 맞지 않을 때 체크한다.-->
          <message>메일형식에 맞지 않습니다.!!!</message>
          </field-validator>
          <field-validator type="requiredstring">
             <param name="trim">true</param>
             <message>메일을 입력하세요!</message>
          </field-validator>
   </field>
</validators>


requiredstring, stringlength, email 등은 정의되어 있는 것을 쓰는 것이기 때문에 자세한 내용은 api를 참고한다.
http://struts.apache.org/2.0.14/docs/validation.html

3) validator.xml 수정

<action name="xml"
       class="com.myhome.validator.actions.XMLRegisterAction"
       method="execute">

4) jsp 수정

 <form method="post" name="regform" action="xml.action">

파일 참조 

Struts2에서 validator 해보기 끝!

 Struts2의 작동 원리

Struts2 Framework Architecture Diagram


 1. Client가 HttpServletRequest를 요청하면 FrontController인 FilterDispatcher가 받는다.

 2. ActionMapper부터 ActionProxy 등을 거쳐 와서 Config 문서인 struts.xml 문서와 추가로 struts.properties 파일을 요구한다. struts.properties는 있으면 로딩하고 없으면 하지 않는다.(없어도 된다)

 3. struts.xml과 strtus.properties문서를  Interceptor가 받아온다. 그리고 Client의 모든 Parameter를 가로챈다.

 4. Interceptor 은 3단계로 나누어져 있다.
1단계에서는 Client의 모든 Paramter를 가로챈다. 
2단계에서는 렌더링 역할을 수행한다.(언어 설정, 보안 설정 등)
3단계에서는 Action의 setter method 를 찾고, 데이터를 푸시하는 역할을 한다.(ActionForm이 필요없다)

 5. Business Logic Controller인 Action에서 setter method 메소드를 받아서 비즈니스로직을 수행한다. 

 6. getter method를 통해 Result로 전달해주거나 받는다. Result에서 적절한 페이지를 선택한다. 이때 Template를 지정한다.(JSP, JSF, Velocity(확장자 : vm), FreeMarker(확장자 : ftl)) 적정할 Template를 잡아서 다시 Interceptor로 보낸다.(getter를 통해서 객체는 머든 상관없다)

 7. 다시 역방향으로 간다. 1단계에서 Result에서 적절한 페이지를 선택할때, 그 페이지를 찾는다. 그리고 그 페이지의 Value Stack(그림에는 없음)을 갖고, Value Stack에다가 데이터를 넣주고 그냥 찍기만 하면 된다.(Spring의 setAttribute 필요없이 받을 수 있다) 

Struts2의 기본적인 작동원리 끝!

+ Recent posts