'개발자의 길'에 해당되는 글 195건

struts 2 - 스트럿츠 2의 defalte설정 2009.07.03
struts 2 - 기본 작동 순서 2009.07.02
struts 1 - exception 처리 2009.07.02
struts1 - Tiles plug-in 2009.07.01
struts 1 - validator 2009.07.01

struts 2 - 스트럿츠 2의 defalte설정

Published on: 2009. 7. 3. 00:58 by louis.dev


1. web.xml 파일의 설정

사용자로부터 요청이 들어오게 되면 가장 먼저 실행되는 것이 Front Controller인 Filter Dispatcher이므로 filter 설정을 먼저 해주어야 한다.

<filter>
   <filter-name>struts2</filter-name>            
   <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
   </filter-class>
</filter>

물론 filter-name은 아무거나 설정해도 된다.

다음으로 filter-mpping부분이다.

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

filter-name은 위에 선언했던 것이고 url-pattern은 무엇이라도 url로 들어오면 filter를 실행 시키겠다는 뜻으로 struts 나 spring 처럼 /*.do 이런식으로 확장자까지 선택해 주면 에러가 발생함으로 쓰지 않도록 한다.
뒤의 확장자는 뒤에 properties파일에서 선언하게 된다.

2. struts.properties 파일을 생성한다.



eclipse의 navigator 탭으로 이동후 src 폴더로 생성한 properties 파일을 옮기면 자동적으로 build의 classes 폴더로 이동하게 되는것을 그림과 같이 확인 할 수 있다.

설정 파일인 struts.xml 과 properties파일은 classes 폴더에서 찾기 때문에 위와 같이 해주어야 한다.

struts.properties
--------------------------------------------------------------------------------------------------
struts.enable.DynamicMethodInvocation=true
struts.i18n.reload=true                                                                       #프로그램을 수정후 서버를 restart 할 필요가 없다.
struts.devMode=true
struts.configuration.xml.reload=true         
struts.custom.i18n.resources=globalMessages
struts.url.http.port=8989                                                                       # was의 port 번호
struts.serve.static=true
struts.serve.static.browserCache=false
struts.configuration.files=struts-default.xml,struts-plugin.xml,struts.xml   # 다음에서 설정된 파일 이름으로 설정 파일을 로딩하겠다.
struts.action.extension=do,action,bit                                                    # url이 .do .action .bit 로 끝나는 것들을 접근을 허용하겠다.
struts.i18n.encoding=euc-kr                                                                # encoding type은 euc-kr이다
--------------------------------------------------------------------------------------------------

3. 위에 설정한 대로 struts.xml 파일을 생성한다.
struts.xml 파일은 다른 action이 설정되어 있는 xml파일을 include하는 형식으로 되어있다.
--------------------------------------------------------------------------------------------------
<?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="info.xml"/>
   <include file="validator.xml"/>
</struts>
--------------------------------------------------------------------------------------------------

4. library파일을 추가 한다.

struts 2의 API를 다운로드 받게 되면
struts-2.0.14 -> apps 폴더의 struts2-blank-2.0.14.war 라는 파일을 압축을 푼다.
struts2-blank-2.0.14.war 파일은 기본적으로 벤더 회사가 제공하는 예제 파일이라고 보면 된다. 이 압축된 폴더에 보면 lib폴더 안에 struts 2를 구동하기 위한 가장 기초적인 libarary파일이 존재하는데 그 파일을 복사해서 붙여넣기 하는 방법을 쓴다.

5. struts.xml 파일에서 include하는 xml파일을 생성한다.

include 하는 파일에는 실질적인 action 부분이 들어있다.
--------------------------------------------------------------------------------------------------
<?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>
   <package name="info" namespace="/info" extends="struts-default">
    <action name="index">
     <result>/WEB-INF/info/register.jsp</result>
    </action>
    <action name="register"
      class="com.myhome.info.actions.InfoRegisterAction"
      method="execute">
     <result>/WEB-INF/info/result.jsp</result>
    </action>
    <action name="list"
      class="com.myhome.info.actions.InfoListAction">
     <result name="success">/WEB-INF/info/list.jsp</result>
    </action>
    <action name="query"
      class="com.myhome.info.actions.InfoQueryAction"
      method="execute">
     <result name="success">/WEB-INF/info/modify.jsp</result>
    </action>
    <action name="update"
      class="com.myhome.info.actions.InfoUpdateAction"
      method="execute">
     <result name="success">/WEB-INF/info/template.jsp</result>
    </action>
    <action name="delete"
      class="com.myhome.info.actions.InfoDeleteAction"
      method="execute">
     <result name="success">/WEB-INF/info/template.jsp</result>
    </action>
   </package>
</struts>
--------------------------------------------------------------------------------------------------
- package : name -> package이름을 설정한다
                  namespac -> url로 맵핑되는 namespace를 선언한다. 만약 http:localhost:8989/struts2/ 가 기본적인 주소라면 namespace는 이 부분 뒤에 들어오는 값이 된다. 즉 http:localhost:8989/strtus2/info  에서 info가 namespace가 되며 저런 url pattern이 들어오면 다음의 패키지를 참조하고 뒤에 http:localhost:8989/struts2/info/index.do 에서 index와 각각의 action name과 비교 하며 같은것을 실행 하게 된다.

- action : name -> url pattern이 이런 이름으로 들어오면 다음을 실행한다.
              class -> 실행할 action class를 선언한다.
              method -> execte메소드를 실행시키겠단 뜻으로 쓰던 안쓰던 defalte가 method="execute" 로 잡혀 있어 상관없다.
-result : name -> 각각의 action Class는 그 결과를 return값으로 설정해 주며 각각은 이미 정해진 문자열이다.(SUCCESS,INPUT,ERROR ect...)
                          각각의 Action Class에서 return 값으로 다음과 같은 전달값들을 전달해 줄때 리턴해 준 문자열과 name과 똑같으면 다음의 페이지로 이동시키게 된다.
여기서 가장 중요한 것은 Action Class에서 전달값이 "SUCCESS" 와 같은 대문자 더라도 XML 문서의 result에서는 "success" 와 같이 소문자로 받아야 된다는 점이다.

6. 실질적인 Businuss Logic을 수행하는 Action Class를 생성한다.
이 클래스는 ActionSupport Class를 상속하고 ActionSupport Class의 execute method를 override 한다.
--------------------------------------------------------------------------------------------------
package com.myhome.info.actions;

import com.opensymphony.xwork2.ActionSupport;
import com.myhome.info.dao.InfoDAO;
import com.myhome.info.vo.InfoVO;

@SuppressWarnings("serial")
public class InfoRegisterAction extends ActionSupport{

 /*form property fields*/
 
 private InfoVO bean;
 
 @Override
 public String execute() throws Exception {
  // TODO Auto-generated method stub
  bean.setWdate(this.getToday());
  new InfoDAO().register(bean);
  return SUCCESS;
 }

 protected String getToday(){
  return new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
 }

 public InfoVO getBean() {
  return bean;
 }

 public void setBean(InfoVO bean) {
  this.bean = bean;
 }
 
}
--------------------------------------------------------------------------------------------------

7. jsp 페이지 생성
jsp 페이지에서는 struts2에서 제공하는 테그라이브러리를 통해 bean을 생성하고 bean에 jsp에서 발생한 데이터를 저장하고 Business Logic Controller로 bean 객체를 전달하게 한다.
--------------------------------------------------------------------------------------------------
<%@ page contentType="text/html;charset=euc-kr"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:bean id="bean" name="com.myhome.info.vo.InfoVO"/>

<html>
  <head>
    <style type="text/css">
       a:active  {font-size: 11pt; text-decoration: none; color: #000000}
  a:link    {font-size: 11pt; text-decoration: none; color: #000000}
  a:visited {font-size: 11pt; text-decoration: none; color: #000000}
  a:hover   {font-size: 11pt; text-decoration: none; color: #000000}
  td        {font-size: 11pt; text-decoration: none; color: #000000}
    </style>
  </head>
  <body>
    <center><br><br>
    <h3><b>Struts2 Action (register)</b></h3>
    <form method="post" action="register.do">
     <table border=0 cellpadding=1 cellspacing=1 bgcolor="#000000">
       <tr height=30 bgcolor="#ffffff">
         <td width=100 align="right"><b>성명</b>&nbsp;
         </td>
         <td width=300 align="left">&nbsp;
            <input type="text" name="bean.name">
         </td>
       </tr>
    <tr height=30 bgcolor="#ffffff">
   <td width=100 align="right"><b>성별</b>&nbsp;
         </td>
   <td width=300 align="left">&nbsp;
   <input type="radio" name="bean.sex" value="남" checked>남
            <input type="radio" name="bean.sex" value="여">여
   </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="bean.tel">
   </td>
    </tr>
    <tr height=30 bgcolor="#ffffff">
    <td align="center" colspan=2>
   <input type="submit" value="전송하기">
            <input type="button" value="리스트"
              onClick="javascript:location.href='list.do'">
    </td>
   </tr>
    </table>
  </form>
 </center>
 </body>
</html> 
--------------------------------------------------------------------------------------------------
- 맨처음 태그를 선언하고 <s:bean>태그로 bean을 설정한다.
- 각각 데이터 입력이 일어나는 form태그의 name을 위에서 선언한 bean의 id를 써주고 그 빈객체에 대응하는 property이름을 넣어주면 자동적으로 발생하는 데이터 들이 bean으로 들어가게 된다.


bean.name -> 이렇게 하면 bean이라고 설정한 InfoVO에 name 이라는 property에 데이터가 입력 된다.

이렇게 되면 이 정보는 ActionSupport를 상속한 class로 이동하게 된다.
그 클래스 에서는
private InfoVO bean; 을 선언하고
InfoVO의 setter method를 통해 데이터가 저장되고 로직을 수행한 후에 getter를 통해 jsp페이지로 다시 정보가 이동하게 된다.

여기서 가장 중요한 점은 jsp 페이지에서 선언한 bean의 id 이름과 ActionClass의 데이터를 받을 오브젝트 이름이 같아야 한다는 점이다.
예)
jsp:
      <s:bean id="valueObject" name="com.myhome.vo.InfoVO">
                          ||
ActionClass         ||
 private InfoVO valueObject;

Action Class를 통과한 데이터가 result.jsp페이지로 이동한다면 result.jsp페이지의
<s:bean id="valueObject" name="com.myhome.vo.InfoVO">
이어야 한다.

register.jsp  --------------------------> Action Class --------------------------->result.jsp
                setter method 로 데이터 전달                       getter method로 데이터 전달



※ struts 2의 태그
① <s:iterator value="list">
list 형태로 데이터가 넘어 왔을때 foreach문 대신 사용한다.

② <s:property value="num">
property 이름으로 바로 접근 할 수 있다.

8. DB 접근을 위한 iBatis 설정

9. Value Objec Class생성

10. DB에 접근하기 위한 DAO 생성

'Framework > STRUTS 2' 카테고리의 다른 글

struts 2 - session 사용하기  (1) 2009.07.05
struts 2 - action을 선언한 xml에서 result property 들  (0) 2009.07.05
struts 2 - validator  (0) 2009.07.03
struts 2 - annotation설정  (0) 2009.07.03
struts 2 - 기본 작동 순서  (0) 2009.07.02

struts 2 - 기본 작동 순서

Published on: 2009. 7. 2. 23:32 by louis.dev


① Clent로 부터 요청을 보내면 Front Controller인 Filter Dispatcher가 요청을 받아 들인다.
② Filter Dispatcher는 /WEB-INF 폴더 밑에 있는 classes 폴더에서 struts.xml 파일을 로딩하고 struts.properties파일을 로딩한다.
    이때 두 파일이 있으면 참조를 하고 없으면 참조 하지 않는다.
③ 설정 파일을 모두 로딩한 후에 그 정보는 Intercepter에게 전달하고 Intercepter에서는 3가지 단계를 수행한다.
    - 1단계 : FrontController에서 전달된 파라미터 정보들을 가로채게 된다.
    - 2단계 : 렌더링(언어설정 ect...), 보안설정을 한다.
    - 3단계 : 다음단계인 Business Logic Controller의 setter method()를 찾고 데이터를 Business Logic Controller의 property에 전달된 데이터를 저장한다

④ 비지니스 로직을 거친 결과를 Business Logic Controller의 getter method() 를 통해 result 로 보내주고 result는 Tempate를 호출해 적당한 출력 폼을 선택한다(JSP, Valocity, FreeMarket)
⑤ 결과값을 역으로 브라우져로 출력해 준다.

struts 1 - exception 처리

Published on: 2009. 7. 2. 00:39 by louis.dev


스트럿츠 1에서는 익셉션 처리 하는 방법이 두가지가 있다.
① Global Exception으로 처리하는 방법
② Action Exception으로 처리하는 방법

1. Global Exception으로 처리하는 방법

1) 에러가 발생되었을때 보여질 jsp 페이지를 생성한다.

-----------------------------------------------------------------------------------------------------
<%@ page contentType="text/html; charset=euc-kr"%>
<%@ page import="org.apache.struts.Globals" %>
<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html"%>
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%>
 
<html>
 <head>
  <title>예외 처리</title>
 </head>

 <body>
  <center>
    <h3><b>예외 핸들러가 전달한 에러 메시지 목록</b></h3>
   <html:messages id="error">
    <li><bean:write name="error"/></li>
   </html:messages>

   <br/><br/>
   <h3>예외객체에서 가져온 예외 메시지</h3>
   <blockquote style="background: wheat;">
 <%
  Exception ex = (Exception)
                 request.getAttribute(Globals.EXCEPTION_KEY);
     if (ex == null) out.println("ex == null");
     else out.println(ex.getMessage());
 %>

   </blockquote>
  </center>
 </body>
</html>
-----------------------------------------------------------------------------------------------------

2) .properties 파일(메시지 번들) 생성

-----------------------------------------------------------------------------------------------------
# exception messages
exception.global=오류가 발생했습니다.
exception.handler={0} : 오류가 발생했습니다. 오류 메시지 : {1}
exception.register=존재하지 않는 이름이 입력되었습니다.
exception.fileNotFound=업로드 파일이 존재하지 않습니다.

# native2ascii -encoding euc-kr ExceptionMessageResource.properties ExceptionMessageResource_ko.properties
-----------------------------------------------------------------------------------------------------

3) 사용할 struts-config.xml 파일에 <global-exceptions>생성

<global-exceptions>
  <exception type="java.lang.Exception"
                   key="exception.global"
                   path="/exception/exception.jsp"/>
 </global-exceptions>

모든 Exception이 발생했을때 다음의 global-exceptions 를 실행한다.

- type : Exception class 설정
- key : properties 파일에 존재하는 에러 key 선택
- path : 에러 발생시 보여줄 페이지 선언
- handler: exception을 처리할 Handler Class 선언
               Handler Class 는 ExceptioHandler class를 상속 받은 구조여야 한다.(Action Exception으로 exception을 처리할때 선언)


4) config.xml 파일에 message-resources 등록하기(.properties파일 경로 지정)

<message-resources parameter="com.myhome.upload.ExceptionMessageResource"/>

2. Action Exception으로 처리하는 방법

1) ExceptioHandler class를 상속받은 class를 생성하고 ExceptionHandler class의 excute() 메소드를 override 한다.

-----------------------------------------------------------------------------------------------------
package com.myhome.handler;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.config.ExceptionConfig;
import org.apache.struts.action.ExceptionHandler;
import org.apache.struts.action.ActionMessage;

import java.util.Date;

public class InfoExceptionHandler extends ExceptionHandler {
 
    public ActionForward execute(Exception ex, 
            ExceptionConfig config,
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
               throws ServletException {
   
     
 /* 발생한 예외시간을 포함해서 새로운 문자열로 구성한다.
  * 액션 메시지의 정보를 리소스번들에 지정한 인수로 전달하기 위해 사용된다.
  * . resource bundle
  *   exception.handler={0} : 오류가 발생했습니다.
  *                     오류 메시지 : {1}
  *  arg[0] => {0}로 연결된다.
  *  arg[1] => {1}로 연결된다.                   
  *
  * */

 String [] args = new String[2];
 long currentTimeMillis = System.currentTimeMillis();
 Date currentTime = new Date(currentTimeMillis);
 args[0] = currentTime.toString(); // 현재 시간을 인자로 저장.
 args[1] = ex.getMessage(); // 오류 메시지를 인자로 저장.
 
 // 지정된 키의 메시지를 메시지 리소스 번들에서 가져와
    //{0}, {1}을 지정된 인자로 대체하여 새로운 메시지 구성.
 ActionMessage errorMessage = new ActionMessage(
                            config.getKey(),args);       
       
 // 예외 정보를 가지고 포워딩할 JSP페이지를 찾는다.
 //<exception path=""/>에 지정된 페이지
 ActionForward forward = new ActionForward(config.getPath());
 
 // 예외 사항들을 request에 저장한다.
 storeException(request,
                       config.getKey(),
                       errorMessage,
                       forward,                         
                       config.getScope());
            return forward;
   }
}

-----------------------------------------------------------------------------------------------------
이 클래스는 익셉션이 발생하였을때 이쪽으로 넘어오며 에러메시지를 request 객체에 담아 에러 메시지를 보여줄 페이지로 보내주게 된다.

에러가 발생하게 되면

<exception key="exception.handler"/> 메시지를 가져다가 현재 시간과 ex.getMessage()를 실행하여 예외의 메시지를 합쳐서 ActionMessage 객체를 구성하게 된다.

그리고 config.getPath()를 이용해서

 <exception path="/exception/exception.jsp"/> 로 지정된 포워딩할 JSP 주소를 얻어다 ActionForward 객체를 구성한다.

최종적으로 storeException()메소드를 실행하여 에러 메시지를 지정된 스코프(config.getScope())에 저장하고는 포워드 객체를 리턴한다.

이제 IOException 이나 NullPointerException이 발생하면 아래와 같은 화면을 보게 된다.




2.struts-config.xml 파일에 <action>태크 밑으로 로컬 exception 영역을 설정한다.

<action path="/upload"
           name="uploadBean"
           scope="request"
           parameter="method"
           unknown="true"
           type="com.myhome.upload.actions.UploadDispatchAction">
         
       <!-- exception handle -->
       <exception key = "exception.handler"
            handler = "com.myhome.handler.InfoExceptionHandler"
            path = "/excetpion.jsp"
            type = "java.lang.NullPointerException">
       </exception>

            <forward name="result"  path="/result.jsp"/>
            <forward name="fail"    path="/fail.jsp"/>
            <forward name="list"    path="/list.jsp"/>
            <forward name="query"   path="/modify.jsp"/>
            <forward name="update"  path="/template.jsp"/>
            <forward name="delete"  path="/template.jsp"/>
       </action>   

type 에 선언된 Action에서 exception이 발생 되었을때 하단의 exception handle에 의해 에러 페이지로 이동한다.

여러종류의 Exception을 처리 할 경우

<exception key="exception.handler"
           handler=“info.handler.InfoExceptionHandler"
           path="/exception/exception.jsp"
           type="java.lang.NullPointerException"/>
<exception  key="exception.handler"
           handler=“info.handler.InfoExceptionHandler"
           path="/exception/exception.jsp"
           type="java.io.IOException"/>

struts1 - Tiles plug-in

Published on: 2009. 7. 1. 21:05 by louis.dev

스트럿츠 1에서는 사용할 수 있는 플러그인은 두개 밖에 없다. validator plug-in과 Tiles plug-in이 그 두가지 이다.
Tiles는 중복되는 웹페이지의 레이아웃을 간단한 설정파일을 통해 쉽게 설정할 수 있고 기존에 include로 페이지를 삽입했을때 보다 유지 보수성이 뛰어나다는 장점을 가지고 있다.

작업 순서
1) strust-tiles-1.3.10.jar파일을 라이브러리에 추가 시킨다.

2)tiles-defs.xml파일을 설정한다.

---------------------------------------------------------------------------------------
<?xml version="1.0" encoding="UTF-8" ?>

 <!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
       "http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd">

<tiles-definitions>
    <definition name=".layout-main"
                path="/tilesModule/classicLayout.jsp">     <!-- 다음과 같은 path로 찾아 들어왔을때 웹페이지의 설정을 한다. 실제 적으로 classicLayout.jsp파일에서 tiles 테그라이브러리를 통해 include할때  아래의 이름으로 include 시키게 된다.-->
        <put name="title"  value="struts framework tiles examples"/>  <!-- title이란이름으로 들어갈 value를 설정 -->
        <put name="header" value="/tilesModule/header.jsp"/>          <!-- jsp페이지에서 header란 이름으로 include했을때 다음의 jsp 페이지를 include 한다. -->
        <put name="menu"   value="/tilesModule/menu.jsp"/>
        <put name="body"   value="/tilesModule/body.jsp"/>
        <put name="footer" value="/tilesModule/footer.jsp"/>
    </definition>
   
    <definition name=".layout-menu1" extends=".layout-main">           <!-- extends: original페이지의 definition 이름을 설정한다. -->
        <put name="body" value="/tilesModule/body-menu1.jsp"/>
    </definition>
   
    <definition name=".layout-menu2" extends=".layout-main">
        <put name="body" value="/tilesModule/body-menu2.jsp"/>
    </definition>
</tiles-definitions>

---------------------------------------------------------------------------------------

3) layout page 생성

---------------------------------------------------------------------------------------
<%@page contentType="text/html; charset=euc-kr"%>
<%@ taglib prefix="tiles" uri="http://struts.apache.org/tags-tiles"%>
<%@ taglib uri="
http://struts.apache.org/tags-html" prefix="html"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title><tiles:getAsString name="title" /></title>
        <html:base/>
    </head>
    <body>
 <h1><tiles:getAsString name="title"/></h1>
    <table border=0 cellpadding=0 cellspacing=1 bgcolor="#a0a0a0" width="100%">
        <tr valign="middle" bgcolor="#ffffff">
            <td colspan=2><tiles:insert attribute="header"/></td>
        </tr>
        <tr height="400" bgcolor="#ffffff">
            <td valign="top"  width="15%">
               <tiles:insert attribute="menu"/>
            </td>
            <td valign="middle" align="center">
               <tiles:insert attribute="body"/>
            </td>
        </tr>
        <tr bgcolor="#ffffff">
            <td colspan=2><tiles:insert attribute="footer"/></td>
        </tr>
    </table>
    </body>
</html>

---------------------------------------------------------------------------------------
위에 처럼 테그라이브러리를 선언하고 tiles 테그라이브러리로 다음의 페이지를 입력할 수 있다.
getAsString은 tiles-defs.xml파일에서 설정한 곳으로 들어가 name을 찾아 스트링을 입력한다.
insert는 tiles-defs.xml파일에서 선언한 jsp페이지를 삽입한다.

4) struts-tilesModule.xml에 plug-in설정
<plug-in className="org.apache.struts.tiles.TilesPlugin">
  <set-property property="definitions-config"  value="/WEB-INF/tiles-defs.xml” /> <!-- tiles-defs파일 위치 설정-->
<!-- 여기서 부터 옵션 -->
  <set-property property="definitions-debug" value="2" /> <!--디버그 수위 value=0 사용안함 value = 2보통 value = 5 max -->
  <set-property property="definitions-parser-details" value="2" />
  <set-property property="definitions-parser-validate" value="true" />
</plug-in>

5) struts-tilesModule.xml 에 action-mapping설정
<action path="/main"  forward=".layout-main" />
<action path="/menu1" forward=".layout-menu1" />
<action path="/menu2" forward=".layout-menu2" />

<controller processorClass="info.process.InfoRequestProcessor"/>
※ processortClass는 반드시 TilesRequestProcessor타입이어야 한다.


6) Request processor class생성
package com.myhome.info.processor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.tiles.TilesRequestProcessor;
public class InfoRequestProcessor extends TilesRequestProcessor{

 @Override
 /* Action으로 호출하기 전 처리할 내용을 기술하는 부분입니다. */
 protected boolean processPreprocess(HttpServletRequest request,
   HttpServletResponse response) {
  
  //form parameter에 대한 인코딩을 수행한다.
  boolean flag = false;
  try{
   request.setCharacterEncoding("euc-kr");
   flag = true;
  }catch(java.io.UnsupportedEncodingException uee){};
  
  return flag;
 }
 
}
request processor class를 tilesReqeustProcessor가 상속하고 있다.

struts 1 - validator

Published on: 2009. 7. 1. 16:57 by louis.dev


struts1 에서 validator를 수행하는 방법은 두가지가 있다.
① 직접 validator logic을 수행하여 validate하는 방법
② validator plug-in을 통한 방법

1. 직접 validator logic을 수행하여 validate하는 방법


- 클라이언트로 들어온 요청은 ActionServlet으로 들어간다.

- ActionServlet은 config 파일에 있는 <action>을 실행하고 action property중에 validate= true 이면 Request processor에게 ActionForm이 validate() method를 가지고있으니 validate()를 실행해라라는 것을 알려준다.

- Request Processor를 거쳐 들어온 데이터는 ActionForm으로 가고 validate()메소드에서 각각의 validate logic을 수행하고 만약 validate에 문제가 있으면 ActionError에 메시지를 누적 시킨다. ActionForm에서 로직을 수행한 결과는 Request Processor에게 전달된다.

- Request Processor는 전달받은 결과중 ActionError에 에러 메시지가 들어있는지를 확인하고 없으면 Action으로 들어가 비지니스로직을 수행하고 에러메시지가 있다면 바로 Client로 돌려 보낸다.




1) MessageResource.properties파일을 만든다.
----------------------------------------------------------------------------------------
#validator message resource

name.error={0} 이름을 입력하세요!!!
age.error={0} 유효하지 않는 나이입니다.
email.error={0} 메일형식에 맞지 않습니다.
----------------------------------------------------------------------------------------
{0} 는 Action class에서 파라미터로 넘겨준 사용자 정의의 스트링으로 맵핑 시켜준다.
예를 들어 ValidatorFormBean class에서

error.add("age",new ActionMessage("age.error","나이 오류!"));

다음과 같은 파라미터로 넘겨오는 경우 나이오류라는 전달 인자가 age.error={0} 에 맵핑되어 에러메시지는
나이오류! 유요하지 않은 나이입니다.

이라는 에러 메시지를 출력하게 된다. 만약 properties 파일에서
age.error = {0} 유효하지 않은 나이 입니다. {1}
이렇게 선언 되어 있고
error.add("age",new ActionMessage("age.error","나이 오류!","나이를정확히 입력해 주세요"));
이렇게 전달인자를 넘겨 준다면 에러메시지 출력 결과는

나이 오류!
유효하지 않은 나이입니다. 나이를 정확히 입력해 주세요

와 같이 에러가 출력된다.

2) FormBean을 설정한다.
          - ActionForm Class를 상속한 class를 생성한다.
          - ActionForm Class 의 validate() 메소드를 override 한다.
          - 각각의 validate logic을 완성한다.
          - validate() method 안의 logic을 완성하고 error가 있을경우 ActionError 인스턴스에 에러 메시지를 add해준다.

----------------------------------------------------------------------------------------
package com.myhome.validator;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;

/**
 *  user login을 통한 validator 구현
 *  ActionForm class에서 validate()를 통해 구현
 *
 */

@SuppressWarnings("serial")
public class ValidatorFormBean extends ActionForm{
 /* form property fields  */
 private int    age;
 private String name;
 private String email;
 
 /*ActionForm class의 validate()를 overriding한다*/
 
 @Override
 public ActionErrors validate(ActionMapping mapping,
   HttpServletRequest request) {
  ActionErrors error = new ActionErrors();
  if(!isNameValid()){
   error.add("name",new ActionMessage("name.error","이름 오류!!"));
  }
  if(!isAgeValid()){
   error.add("age",new ActionMessage("age.error","나이 오류!"));
  }
  if(!isEmailValid()){
   error.add("email",new ActionMessage("email.error","이메일 오류!"));
  }
  return error;
 }
 
 /*validator logics*/
 //이름은 반드시 두자이상 입력을 요구한다.
 protected boolean isNameValid(){
  if(this.getName() == null) return false;
  else if(this.getName().length() < 2) return false;
  return true;
 }
 
 //나이는 20세부터 80세 까지만 허용한다.
 protected boolean isAgeValid(){
  if(this.getAge() < 20 || this.getAge() > 80)
   return false;
  return true;
 }
 
 //이메일 형식이 정확한 지 검사한다.
 protected boolean isEmailValid(){
  int delim = this.getEmail().indexOf('@');
  if(delim < 0)
   return false;
  if(this.getEmail().substring(0,delim).length() < 2)
   return false;
  if(this.getEmail().substring(delim).length() < 2)
   return false;
  return true;
 }
 
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
 
 
}

----------------------------------------------------------------------------------------
주황색 부분이 가장 중요한 부분으로 ActionErrors 인스턴스인 error에 add메소드로 validate가 유효하지 않을때 message를 저장하게 된다.
error.add("name",new ActionMessage("name.error","이름 오류!!"));
이부분에서 앞의 name은 그냥 string형이름으로 정하고 name.error 는 앞에 properties파일에 설정된 key를 불러 들여오고 두번째 전달인자인 "이름오류" properties파일의 name.error ={0} 과 대응되어 결국 두메시지가 합쳐진 형태로 에러 메시지를 출력한다.

3)validate DTO를 생성한다. 일반적인 DTO와 다르지 않다.

4) struts-validatorModule.xml 파일을 생성하고 action과 message-resource, form-bean 영역을 설정한다.
----------------------------------------------------------------------------------------
<form-beans>
          <form-bean name="validatorBean" 
                            type="com.myhome.validator.ValidatorFormBean"/>
</form-beans>

<action-mappings>
   <action path="/register"
          name="validatorBean"
          scope="request"
          validate="true"
          input="/register.jsp"
          type="com.myhome.validator.ValidatorRegisterAction">
         <forward name="success" path="/result.jsp"/>
        </action>   
   </action-mappings>

<message-resources parameter="com.myhome.validator.ValidatorMessageResource"/>
----------------------------------------------------------------------------------------
여기서 가장 중요한 부분은 action mapping부분의 validate="true" 이다. 이부분을 true로 놓아야 action Servlet이 request processor에게 actionForm의 validate() 메소드를 실행 시켜야 된다 라는 것을 알려주기 때문이다.


5). web.xml에 struts-validatorModule.xml을 등록한다.
<init-param>
   <param-name>config/validatorModule</param-name>
   <param-value>/WEB-INF/config/struts-validatorModule.xml</param-value>
  </init-param>

6)jsp 페이지 에서 struts 태그를 사용하여 ErrorMessage를 출력한다.

<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html"%>
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%>
<%@ taglib prefix="logic" uri="http://struts.apache.org/tags-logic"%>

<logic:messagesPresent> <!-- message stack에 에러메시지가 있으면 다음을 실행한다. -->
    <tr height=30 bgcolor="#ffffff">
      <td align="left" colspan="2">
        <html:messages name="error"> <!-- 메시지 id는 임의로 정의하고 -->
         <span style="font-size:10pt; color:red">
          <li><bean:write name="error"/></li> <!-- 메시지 이름이 ERROR인 애를 출력한다. -->
           </span>
         </html:messages>
      </td>
    </tr>
</logic:messagesPresent>

※struts-validatorModule.xml에 설정한 form-bean 이름으로 jsp페이지 까지 넘어 오기 때문에 <form>테그 안의 데이터 들을 그대로 남겨 두려면 EL 테그를 쓰면 된다.
예)
<input type="text" name="email" size=35 value="${validatorBean.email}">
이렇게 하면 데이터를 입력하고 서브밋을 눌러 ActionForm에 갔다가 다시 jsp페이지로 오면 사용자가 입력한 데이터가 다음의 bean에 입력되어 있기때문에 그대로 데이터를 살려 둘 수 있다.


2. validator plug-in을 통한 방법

validator plug-in방식으로 하려면 라이브러리 파일이 필요하지만 struts-core 라이브러리에 있기 때문에 특별히 라이브러리를 추가할 필요가 없다.

작업순서

1)validator Formbean 생성
VaidatorForm class를 상속받은 Formbean class를 작성한다.
----------------------------------------------------------------------------------------
package com.myhome.validator;

import org.apache.struts.validator.ValidatorForm;


@SuppressWarnings("serial")
public class ValidatorPropertyBean extends ValidatorForm implements java.io.Serializable{

 /*Form property fields*/
 private String name;
 private int    age;
 private String email;
 
 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;
 }
 
 
}
----------------------------------------------------------------------------------------

2)struts-validatorModule(사용할 xml파일).xml 에 validator plug-in 설정을 한다.

<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
         <set-property
              property="pathnames"
              value="/org/apache/struts/validator/validator-rules.xml,
                     /WEB-INF/validation.xml"/><!-- 뒤에 xml은 우리가 만든 validation xml 파일 -->
     </plug-in>

3)struts-validatorModule(사용할 xml파일).xml 에 form-bean설정을 한다.
<form-bean name="propertyBean"
          type="com.myhome.validator.ValidatorPropertyBean"> <!-- validation.xml(사용자가 validate할 옵션을 정해준 xml 파일)에서 사용한 bean 이름과 같아야 한다. -->
      <!-- validatorForm을 상속받은 bean의 property와 똑같이 설정한다 -->
      <form-property name="name"
            type="java.lang.String"/>
      <form-property name="age"
            type="java.lang.Integer"/>
      <form-property name="email"
            type="java.lang.String"/>
     </form-bean> 

4)validation.xml(validation할 설정이 들어있는 xml) 생성

required – 폼 데이터가 입력되지 않을 때 검증한다.
minlength – 폼 데이터의 최소길이를 설정하여 검증한다.
maxlength – 폼 데이터의 최대길이를 설정하여 검증한다.
mask – 필요한 문자만 입력되었는 지 검증한다.
intRange – 폼데이터에서 정수의 범위를 설정하여 검증한다.
email – 이메일 형식에 맞게 입력되었는 지 검증한다.

http://struts.apache.org/1.3.8/faqs/validator.html 가면 더 확인 할 수 있다.

----------------------------------------------------------------------------------------
<?xml version="1.0" encoding="euc-kr" ?>
<!DOCTYPE form-validation PUBLIC
     "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.3.0//EN"
     "http://jakarta.apache.org/commons/dtds/validator_1_3_0.dtd">

<form-validation>
  <formset>
 <form name="propertyBean">  <!-- struts-validatorModule에서 form-bean 이름과 같아야 함 -->
     <field property="name" depends="required,minlength,mask">   <!--property : form-bean에 설정되어 있는 property, depends: 미리 설정되어 있는 옵션들을 석어 준다 -->
        <arg key="propertyBean.name"/>    <!-- form-bean 이름이 propertyBean인곳의 property중 name을 가지고 아래의 validation을 처리하겠다. -->
        <arg name="minlength" key="${var:minlength}" resource="false" position="0"/> 
     <arg name="mask" key="${var:mask}" resource="false" position="1"/>
<!--
      name: 윗쪽에 기술된 미리 작성된 validation을 하기 위한 정의된 것을 가져와서 쓴다
      key: 아래의 <var>태그에 선언된 value를 가져와서 validation에서 사용한다.
      position: 먼저 validation 되는 순서를 정한다. 아래의 경우 글자 수가 2개 이상이 아니거나 한글이 들어오지 않을 경우 체크하는것으로서
                   .properties 설정된 것이 로딩되어 경고 메시지를 출력한다.
-->         
           <var>
              <var-name>minlength</var-name>
              <var-value>2</var-value>
           </var>
           <var>
              <var-name>mask</var-name>
              <var-value>^[&#44032;-&#55203;]*$</var-value> <!-- 한글 외에 다른것을 다 걸러준다 -->
           </var>
     </field>
    
     <field property="age" depends="required,integer,intRange">
        <arg key="propertyBean.age" position="0" />
        <arg name="intRange" key="${var:min}" position="1" resource="false"/>
        <arg name="intRange" key="${var:max}" position="2" resource="false"/>
        <var>
         <var-name>min</var-name>
         <var-value>20</var-value>
        </var>
        <var>
         <var-name>max</var-name>
         <var-value>80</var-value>
       </var>
        </field>

     <field property="email" depends="required,email">
          <arg key="propertyBean.email"/>
     </field>
 </form>
  </formset> 
</form-validation>
----------------------------------------------------------------------------------------
5) struts-validatorModule.xml 에 action-mapping을 선언한다.
<action path="/register"
          name="propertyBean"
          scope="request"
          validate="true"
          input="/register.jsp"
          type="com.myhome.validator.ValidatorRegisterAction">
         <forward name="success" path="/result.jsp"/>
        </action> 
validate는 반드시 true로 설정해 주어야 한다.

6) properties 파일 생성과 선언

errors.required=필수 입력항목입니다.
errors.minlength=최소 2자이상 입력해야합니다.
errors.email=메일형식이 맞지 않습니다.
errors.invalid=사용할 수 없는 문자가 입력되었습니다.
errors.range=등록할 수 없는 나이입니다.
----------------------------------------------------------------------------
앞의 errors는 임의로 아무거나 설정할 수 있으나 뒤의 string은 validator plug-in에 있는것으로만 설정해야 한다.
다음을 입력하고 properties 파일로 저장한다. 그리고 struts-validatorModule.xml에 message-resource를 등록한다.

<message-resources parameter="com.myhome.validator.ValidatorMessageResource"/>

7)jsp 페이지 설정
<logic:messagesPresent> <!-- message stack에 에러메시지가 있으면 다음을 실행한다. -->
    <tr height=30 bgcolor="#ffffff">
      <td align="left" colspan="2">
        <html:messages name="error"> <!-- 메시지 id는 임의로 정의하고 -->
         <span style="font-size:10pt; color:red">
          <li><bean:write name="error"/></li> <!-- 메시지 이름이 ERROR인 애를 출력한다. -->
           </span>
         </html:messages>
      </td>
    </tr>
</logic:messagesPresent>