Struts 1 - 스트럿츠 1의 다양한 Action Class 들 part 2

Published on: 2009. 6. 29. 23:39 by louis.dev


1. LookupDispatchAction




getKeyMethodMap() 메서드를 구현하고 리소스 번들의 키와 메소드명을 매핑한다. 기본적으로 파라미터로 method 이름을 전달하여 그것을 통하여 method를 실행하것으로 DispatchAction과 유사한 방법으로 작동 된다.

작업순서

1)위의 클래스에서 getKeyMethodMap()에서 mapping을 해야 하기 때문에 .properties 로 확장자가 끝나는 메시지번들을 생성한다.

2)LookupDispatchAction Class를 상속받은 Class를 생성하고 LookupDispatchAction Class의 getKeyMethodMap()를 Override 하여 구현한다.

3)struts-config-lookup.xml 파일을 생성한다.

4)web.xml 에 struts-config-lookup.xml파일을 설정한다.

5)LookupDispatchAction 을 사용할 jsp 페이지 에서 DispatchAction에서 했던것과 동일 한방법으로 hidden으로 값을 숨기고 전달한다.


작업 방법
1)mapping을 위한 메시지 번들(.properties)를 생성한다.

-이클립스 자체에서 .properties파일을 생성하면 에러가 발생한다. 물론 플러그인을 추가하여 이클립스를 통해 properties파일을 생성 할 수 있지만 일단 메모장에서 작업하고 가져오는 방법을 취한다.

InfoMessageResource.properties(Original File)
------------------------------------------------------------------------------------------------
# struts1 lookup message bundle
# file name : InfoMessageResource.properties

lookup.register = 등록
lookup.list = 리스트
lookup.query = 쿼리
lookup.update = 갱신
lookup.delete = 삭제

# 국제회(Locale) 표준코드 (Unicode)로 변환
# native2ascii [-encoding 코드값] 원시파일 대상파일
# 코드값 : euc-kr, ksc5601, ms949, utf-16

# natice2ascii -encoding euc-kr InfoMessageResource.properties InfoMessageResource_ko.properties
------------------------------------------------------------------------------------------------
다음의 내용을 메모장을 통해 작성후 eclipse의 패키지에 끌어다 놓는다.
#은 주석이다.

가장 핵심 적인 부분은

lookup.register = 등록
lookup.list = 리스트
lookup.query = 쿼리
lookup.update = 갱신
lookup.delete = 삭제

이부분 인데 나중에 LookupDispatchAction Class를 상속한 파일에서 getKeyMethodMap() 메소드를 오버라이딩 하고 거기서 mapping시킬때 사용한다. 위와 같이 한글로 만들 수 있으며 한글로 저장하고 바로 properties파일을 이클립스에 끌어다 놓으면 한글이 깨진다..

------------------------------------------------------------------------------------------------
# struts1 lookup message bundle
# file name : InfoMessageResource.properties

lookup.register = µî·Ï
lookup.list = ¸®½ºÆ®
lookup.query = Äõ¸®
lookup.update = °»½Å
lookup.delete = »èÁ¦

# ±¹Á¦È¸(Locale) Ç¥ÁØÄÚµå (Unicode)·Î º¯È¯
# native2ascii [-encoding Äڵ尪] ¿ø½ÃÆÄÀÏ ´ë»óÆÄÀÏ
# Äڵ尪 : euc-kr, ksc5601, ms949, utf-16

# native2ascii -encoding euc-kr InfoMessageResource.properties InfoMessageResource_ko.properties
------------------------------------------------------------------------------------------------
그러므로 맨아래 부분에 처리된 주석과 같이 인코딩 타입을 euc-kr로 변환하는 작업을 해 주어야 하며 jdk/bin폴더 안에 있는 native2ascii 를 통해 변환 할 수 있다.

          [native2ascii를 통해 변환 하는 방법]
          1.콘솔창을 실행하고 맨처음 properties파일을 생성한 위치로 이동을 한다.
 

          2. 이동한 곳에서 native2ascii 사용하여 encoding타입을 euc-kr타입으로 변경한다.
          native2ascii [-encoding] [코드값] [원시파일] [목적파일]
          형식으로 작업하면 된다.
         
          예) native2ascii -encoding euc-kr InfoMessageResource.properties InfoMessageResource_ko.properties

          를 콘솔창에 쓴다.


          그러면 위와 같이 InfoMessageResource_ko.properties파일이 생성 된 것을 볼 수 있고 인코딩 되어 있는 것을 확인 할 수 있다.
          InfoMessageResource_ko.properties
          ----------------------------------------------------------------------------------------
          # struts1 lookup message bundle
          # file name : InfoMessageResource.properties

          lookup.register = \ub4f1\ub85d
          lookup.list = \ub9ac\uc2a4\ud2b8
          lookup.query = \ucffc\ub9ac
          lookup.update = \uac31\uc2e0
          lookup.delete = \uc0ad\uc81c

          # \uad6d\uc81c\ud68c(Locale) \ud45c\uc900\ucf54\ub4dc (Unicode)\ub85c \ubcc0\ud658
          # native2ascii [-encoding \ucf54\ub4dc\uac12] \uc6d0\uc2dc\ud30c\uc77c \ub300\uc0c1\ud30c\uc77c
          # \ucf54\ub4dc\uac12 : euc-kr, ksc5601, ms949, utf-16

          # native2ascii -encoding euc-kr InfoMessageResource.properties InfoMessageResource_ko.properties
          ----------------------------------------------------------------------------------------
          
         ※만약 natice2ascii에 대해서 찾을 수 없다는 에러가 나오면 환경변수중에 path를 설정하지 않은 것이다. path를 설정해 주면 바로 사용해 줄 수        있다.

          3) 만들어진 두개의 파일을 elipse의 원하는 곳으로 복사를 해서 가지고 온다.

          4) config.xml 파일에 .properties파일 경로를 설정해 준다.
          <message-resources parameter="com.myhome.lookup.InfoMessageResource" />

2)LookupDispatchAction Class를 상속한 InfoLookupDispatchAction Class(임의)를 생성한다.

----------------------------------------------------------------------------------------
package com.myhome.lookup;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.LookupDispatchAction;


import com.myhome.info.beans.InfoFormBean;
import com.myhome.info.dao.InfoDAO;
import com.myhome.info.dto.InfoDTO;

public class InfoLookupDispatchAction  extends LookupDispatchAction {
 
 @Override
 protected Map<String,String> getKeyMethodMap() {
  
  Map<String,String> map = new HashMap<String, String>();
  map.put("lookup.register", "register");  //메시지번들에 있는 키와 같아야 한다. 뒤에는 메소드 명이다.
  map.put("lookup.list", "list");
  map.put("lookup.query", "query");
  map.put("lookup.update", "update");
  map.put("lookup.delete", "delete");
  return map;
 }

 public ActionForward register(ActionMapping mapping,
     ActionForm form,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception{

 /*form parameter를 bean으로 받는다*/
  InfoFormBean bean = new InfoFormBean();
  bean.setName(request.getParameter("name"));
  bean.setSex(request.getParameter("sex"));
  bean.setTel(request.getParameter("tel"));
  
  /*bean property 를 dto로 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  dto.setWdate(this.getWdate());
  
  /*info table에 연동한다.*/
  
  new InfoDAO().register(dto);
  
  /*result.jsp로 포워드하기 위해 리퀘스트 영역에 dto를 binding한다
  * */
  request.setAttribute("dto", dto);
  
  
  return mapping.findForward("result");
 }
 
 public ActionForward list(ActionMapping mapping,
     ActionForm form,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception{
  
  List<InfoDTO> list = null;
  
  list = new InfoDAO().getAllQuery();
  
  request.setAttribute("list", list);
  
  return mapping.findForward("list");
 }
 
 public ActionForward query(ActionMapping mapping,
     ActionForm form,
     HttpServletRequest request,
     HttpServletResponse response)
     throws Exception{
  InfoFormBean bean = (InfoFormBean)form;
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  
  //쿼리된 object를 리퀘스트 영역에 바인딩 한다.
  
  request.setAttribute("dto", new InfoDAO().getQuery(dto));
  
  return mapping.findForward("query");
 }
 
 public ActionForward update(ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception{
  /*form parameter를 InfoFormBean으로 받는다*/
  
  /**
  *  ActionForm의 역할
  *   Form parameter의 정보를 참조하기 위해
  *   ActionForm의 객체를 초기화 한다 - reset()
  * 
  *   form parameter의 정보를 받아 유효성 검사를 실시한다 - validate()
  * 
  *   참조한 폼 정보를 form-bean에 설정도니 bean으로 전달한다.
  * */
 
  InfoFormBean bean = (InfoFormBean)form;
  
  /*bean의 객체를 Entity(DTO)로 property를 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  
  new InfoDAO().update(dto);
  
  
  return mapping.findForward("update");
 }
 
 public ActionForward delete(ActionMapping mapping,
      ActionForm form,
      HttpServletRequest request,
      HttpServletResponse response)
      throws Exception{
 
  InfoFormBean bean = (InfoFormBean)form;
  
  /*bean의 객체를 Entity(DTO)로 property를 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  new InfoDAO().delete(dto);
  return mapping.findForward("delete");
 }
 protected String getWdate(){
  return new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
 }

}
----------------------------------------------------------------------------------------

이 클래스 에서 가장 중요한 부분은 getKeyMethodMap() 부분이다.
Map을 한개 선언한 뒤에 위의 properties에서 선언한 대로 map에 집어 넣으면 된다.

  map.put("lookup.register", "register");  
  map.put("lookup.list", "list");
  map.put("lookup.query", "query");
  map.put("lookup.update", "update");
  map.put("lookup.delete", "delete");

앞의 lookup.~~ 는 properties파일에 정의된 부분과 같아야 되며 뒤에는 실행될 메소드 이름이다.


3)struts-config-lookup.xml 을 생성한다.

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

<struts-config>
 <action-mappings>
  <action path = "/lookupIndex"
    type = "org.apache.struts.actions.ForwardAction"
    parameter="/lookup/register.jsp"/>
  
  <!--
   unknown은 input속성을 대체하기 위한 속성이다.
   입력폼이 여러개 발생할 때 사용된다.
   template.jsp는 list.do로 보내면 어디로 가야 할지 모르기때문에
  -->
  
  <action path = "/lookup"
    name = "bean"
    scope = "request"
    unknown = "true"
    parameter = "method"
    type = "com.myhome.lookup.InfoLookupDispatchAction">
   
   <forward name="result" path = "/lookup/result.jsp"/>
   <forward name="list" path = "/lookup/list.jsp"/>
   <forward name="query" path = "/lookup/modify.jsp"/>
   <forward name="update" path = "/lookup/template.jsp"/>
   <forward name="delete" path = "/lookup/template.jsp"/>
  
  </action>
 </action-mappings>
 
 <!-- Message Resources Definitions -->
 <!-- .property 파일을 설정 -->
 <message-resources parameter="com.myhome.lookup.InfoMessageResource" />
 
</struts-config>
-----------------------------------------------------------------------------------------
가장 핵심적인 부분은 굵은 선의 <action></action>이 핵심이다. DispatchAction 과 같은 형태로 선언 되어 있으며 jsp 페이지 에서 hidden name이 method인 것을 value를 받아 type로 선언된 class로 이동하여 getKeyMethodMap() 를 실행하고 mapping을통해 메소드가 실행된다.

4. web.xml에 config파일을 등록한다

-----------------------------------------------------------------------------------------
<param-value>
   /WEB-INF/struts-config.xml,
   /WEB-INF/struts-config-dispatch.xml,
   /WEB-INF/struts-config-mapping.xml,
   /WEB-INF/struts-config-lookup.xml  
  </param-value>
-----------------------------------------------------------------------------------------

5. jsp페이지에서 hidden값으로 넘겨준다.

<input type="hidden" name="method" value="등록">

이렇게 선언을 하고 submit이 되면
properties파일을 거쳐 lookup.register = 등록 과 같은 맵핑을 수행하게 된다. 이렇게 맵핑된 것은 LookupDispatchAction class의 getKeyMethodMap() 부분에서 map.put("lookup.register", "register"); 를 통해 register method가 실행 되게 된다.

           

Struts 1 - 스트럿츠 1의 다양한 Action Class 들 part 1

Published on: 2009. 6. 26. 17:16 by louis.dev

1. ForwardAction Class


만약 기본타입처럼 Request Process를 거치지 않고 바로 뷰 페이지를 요청 할때는 다음과 같이 선언 할 수 있다.

<action path = "/index"  forward = "/info/register.jsp"/>

하지만 이렇게 action을 설정 하게 되면 위의 그림에서 보듯이 ActionServlet 에서 들어와서 Request processor를 거쳐 바로 ViewPage로 이동 하게 된다. 하지만 ForwardAction 을 쓰게 되면 Request Processor에서 ActionForm으로 넘어가 모든 로딩을 거쳐 ViewPage를 요청하게 할 수 있다.

<action path="/index"
          type = "org.apache.struts.actions.ForwardAction"
          parameter = "/info/register.jsp"/>

- type : 여기서 struts에서 제공하는 ForwardAction Class를 설정한다.
- parameter : 보여줄 view page의 경로를 설정 한다.

2.IncludeAction Class


defalte를 사용하면 Action에서 로직을 실행한후 ActionMapping을 통해 ActionForward로 이동후 Request Processor로 이동한후 view Page로 이동하는데 IncludeAction Class를 사용하면 ActionForward 에서 RequestProcessor를 거쳐서 View Page로 이동하는 것이아니라 바로 View Page로 이동할 수 있다.

- 장점 : ViewPage로 빠른 이동이 가능하다(검색 등에 사용)
- 단점 : Request Prcessor를 거쳐 가지 않기 때문에 processe method에서 실행하는 page Encoding이라 던가 validator를 사용할 수 없다.

예)
<action path="/index"
          type = "org.apache.struts.actions.IncludeAction"
          parameter = "/info/register.jsp"/>

3. DispatchAction Class
일반적으로 Action class를 상속받아 사용하게 되면 하나의 로직당 하나의 Class만을 생성 해야 하기 때문에 Class Over Head가 발생하기 쉽다. 이럴때는 Action Class를 상속 받지 않고 DispatchAction Class를 상속받고 그안에 메소드 형식으로 구현 하기 때문에 클래스 한개에서 모두 처리 할 수 있다.
하나의 클래스에서 이름이 다른 여러개의 ActionForward를 사용 할 수 있다.


다음 그림과 같이 jsp 페이지 에서는 form 태그 안에 hidden 으로 사용할 method 이름을 value로 넘겨 준다. value가 DispatchAction 을 상속 받은 클래스의 method 와 이름이 같아야 클래스에서 method가 실행 된다.

다음으로는 struts-config.xml 파일의 <action mapping>안의 내용이다
여기서 눈여겨 볼 내용은 type 과 parameter 이다.

- type : DispatchAction을 상속 받은 클래스의 위치를 지정
- parameter : jsp page의 hidden 태그의 name과 parameter 의 값과 같아야 한다.

즉 jsp페이지에서 히든으로 넘겨주는 value가 각각의 메소드 이름일때 다음의 것들이 실행 된다는 것이다.

ex)struts-config.xml

<struts-config>
 <action-mappings>
  <action path = "/dispatchIndex"
    type = "org.apache.struts.actions.ForwardAction"
    parameter="/dispatch/register.jsp"/>
  
  <!--
   unknown은 input속성을 대체하기 위한 속성이다.
   입력폼이 여러개 발생할 때 사용된다.
   template.jsp는 list.do로 보내면 어디로 가야 할지 모르기때문에
  -->
  
  <action path = "/dispatch"
    name = "bean"
    scope = "request"
    unknown = "true"
    parameter = "method"
    type = "com.myhome.dispatch.InfoDispatchAction">
   
   <forward name="result" path = "/dispatch/result.jsp"/>
   <forward name="list" path = "/dispatch/list.jsp"/>
   <forward name="query" path = "/dispatch/modify.jsp"/>
   <forward name="update" path = "/dispatch/template.jsp"/>
   <forward name="delete" path = "/dispatch/template.jsp"/>

  
  </action>
  
 </action-mappings>

위와 같이 forward 이름이 각 method마다 달라야 한다.


구현은 jsp 페이지 에서

1) DispatchAction을 상속 받은 클래스 생성
EX)
package com.myhome.dispatch;

import java.util.List;

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

import org.apache.commons.beanutils.BeanUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.actions.DispatchAction;

import com.myhome.info.beans.InfoFormBean;
import com.myhome.info.dao.InfoDAO;
import com.myhome.info.dto.InfoDTO;

 

public class InfoDispatchAction extends DispatchAction{
 
 public ActionForward register(ActionMapping mapping,
          ActionForm form,
          HttpServletRequest request,
          HttpServletResponse response)
          throws Exception{
  
  /*form parameter를 bean으로 받는다*/
  InfoFormBean bean = new InfoFormBean();
  bean.setName(request.getParameter("name"));
  bean.setSex(request.getParameter("sex"));
  bean.setTel(request.getParameter("tel"));
  
  /*bean property 를 dto로 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  dto.setWdate(this.getWdate());
  
  /*info table에 연동한다.*/
  
  new InfoDAO().register(dto);
  
  /*result.jsp로 포워드하기 위해 리퀘스트 영역에 dto를 binding한다
   * */
  request.setAttribute("dto", dto);
  
  
  return mapping.findForward("result");
 }
 
 public ActionForward list(ActionMapping mapping,
         ActionForm form,
         HttpServletRequest request,
         HttpServletResponse response)
         throws Exception{
  
  List<InfoDTO> list = null;
  
  list = new InfoDAO().getAllQuery();
  
  request.setAttribute("list", list);

  return mapping.findForward("list");
 }
 
 public ActionForward query(ActionMapping mapping,
         ActionForm form,
         HttpServletRequest request,
         HttpServletResponse response)
         throws Exception{
  InfoFormBean bean = (InfoFormBean)form;
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  
  //쿼리된 object를 리퀘스트 영역에 바인딩 한다.
  
  request.setAttribute("dto", new InfoDAO().getQuery(dto));

  return mapping.findForward("query");
 }
 
 public ActionForward update(ActionMapping mapping,
         ActionForm form,
         HttpServletRequest request,
         HttpServletResponse response)
         throws Exception{
  /*form parameter를 InfoFormBean으로 받는다*/
  
  /**
   *  ActionForm의 역할
   *   Form parameter의 정보를 참조하기 위해
   *   ActionForm의 객체를 초기화 한다 - reset()
   * 
   *   form parameter의 정보를 받아 유효성 검사를 실시한다 - validate()
   * 
   *   참조한 폼 정보를 form-bean에 설정도니 bean으로 전달한다.
   * */
  
  InfoFormBean bean = (InfoFormBean)form;
  
  /*bean의 객체를 Entity(DTO)로 property를 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  
  new InfoDAO().update(dto);
  

  return mapping.findForward("update");
 }
 
 public ActionForward delete(ActionMapping mapping,
         ActionForm form,
         HttpServletRequest request,
         HttpServletResponse response)
         throws Exception{

  InfoFormBean bean = (InfoFormBean)form;
  
  /*bean의 객체를 Entity(DTO)로 property를 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  new InfoDAO().delete(dto);
  return mapping.findForward("delete");
 }
 protected String getWdate(){
  return new java.text.SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date());
 }
 
}


4.MappingDispatchAction Class

DispatchAction은 각 사용할 method를 hidden값으로 받아서 xml에서 세팅 해주어야 한다. 그리고 DispatchAction을 사용하면 input 테그에서 데이터를 받을때 다양한 값을 받을 수 없기 때문에 MappingDispatchAction을 사용한다.

1)MappingDispatchAction을 상속받아 클래스를 생성한다.
(DispatchAction Class와 다를 것이 없다)

2)xml을 설정한다.
<action-mappings>
  <action path="/mappingIndex"
    type = "org.apache.struts.actions.ForwardAction"
    parameter="/mapping/register.jsp" />
  
  <action path="/mappingRegister"
    parameter="register"
    type="com.myhome.dispatch.InfoMappingDispatchAction">
   <forward name="result" path="/mapping/result.jsp"/>
  </action>
  
  <action path="/mappingList"
    parameter="list"
    type="com.myhome.dispatch.InfoMappingDispatchAction">
   <forward name="list" path="/mapping/list.jsp"/>
  </action>
  
  <action path="/mappingQuery"
    parameter="query"
    type="com.myhome.dispatch.InfoMappingDispatchAction"
    name="bean"
    scope="request"
    input="/mapping/modify.jsp">
   <forward name="query" path="/mapping/modify.jsp"/>
  </action> 
  
  <action path="/mappingUpdate"
    parameter="update"
    type="com.myhome.dispatch.InfoMappingDispatchAction"
    name="bean"
    scope="request"
    input="/mapping/modify.jsp">
   <forward name="update" path="/mappingList.do" redirect="true"/>
  </action>
  
  <action path="/mappingDelete"
    parameter="delete"
    type="com.myhome.dispatch.InfoMappingDispatchAction"
    name="bean"
    scope="request"
    input="/mapping/modify.jsp">
   <forward name="delete" path="/mappingList.do" redirect="true"/>
  </action>

  
 </action-mappings>

-paramether : MappingDispatchAction Class의 method 이름이다.

이렇게 구현하면 jsp 페이지에서 hidden으로 넘겨줄 필요가 없다.

Struts 1 - ActionForm 사용하기

Published on: 2009. 6. 26. 16:31 by louis.dev


1.ActionForm Class를 상속받아 FormBean Class를 만든다.
ex)InfoFormBean.java
package com.myhome.info.beans;

import org.apache.struts.action.ActionForm;

@SuppressWarnings("serial")
public class InfoFormBean extends ActionForm{
 
 private int num;
 private String name;
 private String sex;
 private String tel;

 //사용자 jsp페이지에서 파라미터로 넘어오는 파라미터 네임과 같아야 한다.
 public int getNum() {
  return num;
 }
 public void setNum(int num) {
  this.num = num;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getSex() {
  return sex;
 }
 public void setSex(String sex) {
  this.sex = sex;
 }
 public String getTel() {
  return tel;
 }
 public void setTel(String tel) {
  this.tel = tel;
 }
 
}

2.struts-config.xml 에서 form-bean을 설정한다.

1) 기본적인 ActionForm을 사용할때
<form-beans> 

        <form-bean
            name="bean"  
            type="com.myhome.info.beans.InfoFormBean"/>
</form-beans>

- name : 다른 config파일에서 사용할 이름을 사용자 편의 대로 정의 한다.
- type: 처음의 ActionForm Class를 상속받은 클래스의 패키지명과 클래스 이름을 설정한다.(InfoFormBean은 사용자 임의의 Class)

2) DynaActionForm 을 사용할때

- 사용자로 부터 파라미터로 넘어오는 값이 bean Class안에 정의 되어 있지 않거나 사용자로부터 어떠한 값이 넘어 올지 알 수 없을때 사용한다.
- ActionForm 처럼 ActionForm Bean Class를 만들 필요는 없고 xml 상에 선언만 해주면 된다.

<form-beans> 
        <!--
         DynaActionForm은 예측할 수 없는 파라미터를 참조할때 사용한다.
        -->
        <form-bean
         name="dyna"
         type = "org.apache.struts.action.DynaActionForm">
         <!--
          form bean에 존재하지 않는 파라미터를 참조하기 위해 property를 설정한다.
          -->
          <form-property name="num" type="java.lang.Integer"/>
          <form-property name="name" type="java.lang.String"/>
          <form-property name="sex" type="java.lang.String"/>
          <form-property name="tel" type="java.lang.String"/>
          <form-property name="wdate" type="java.lang.String"/>
        </form-bean>
         
    </form-beans>

- name : ActionForm 와 같은 용도
- type : struts에서 제공되는 클래스를 사용하는 것이기 때문에 직접 DynaActionForm을 설정해 준다.
- <form-property> : 저장될 이름을 선언해 준다.



3.struts-config.xml 파일의 <action-mapping>에 <action>태그와 함께 설정한다.

1) ActionForm을 상속한 bean을 사용할때
예)
<action path = "/update"
          name = "bean"
          scope = "request"
          input = "/info/modify.jsp"
          type = "com.myhome.info.actions.InfoUpdateAction">
     <forward name="success" path="/list.do" redirect="true"/>
</action>

- path : 주소창에 들어오는 URL 패턴, 이때 web.xml에 선언한 .do는 제거 하고 선언한다.
- name : 상단의 <form-beans>태그에 선언된 form-bean중 사용할 form-bean name을 적어 준다.
- scope : "request|session|application" - 다음의 영역으로 들어오는 정보
- input : 입력받은 폼 페이지 명 명시 - 정의된 곳에서 들어오는 데이터를 사용하겠다.
- type: Bussiness Logic을 수행할 Action Class 선언
- <forward> : Action class에서 actionForward로 'success' 를 보내면 path로 선언된 곳으로 보내겠다.
                    redirect = forward 부분에서 path만 잡아 주면 주소창은 변하지 않고 페이지만 변경 시킨다. 그래서 redirect를 true를 설정하면 주소 까지 바뀌어 버린다.

2)DynaActionForm 을 사용할 때
예)
<action path="/delete"
          name = "dyna"
          scope = "request"
          input= "/info.modify.jsp"
          type = "com.myhome.info.actions.InfoDeleteAction">
   <forward name = "success" path = "list.do" redirect="true" />
</action>

※참고 : ActionForm 을 사용할때 꼭 필요한 attribute 들은 name, scope, input 이다.

 4. Action에서 사용 방법

public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {
  
  /*form parameter를 InfoFormBean으로 받는다*/
  
  /**
   *  ActionForm의 역할
   *   Form parameter의 정보를 참조하기 위해
   *   ActionForm의 객체를 초기화 한다 - reset()
   * 
   *   form parameter의 정보를 받아 유효성 검사를 실시한다 - validate()
   * 
   *   참조한 폼 정보를 form-bean에 설정된 bean으로 전달한다.
   * */
  
  InfoFormBean bean = (InfoFormBean)form;
  
  /*bean의 객체를 Entity(DTO)로 property를 복사한다.*/
  InfoDTO dto = new InfoDTO();
  BeanUtils.copyProperties(dto, bean);
  
  new InfoDAO().update(dto);
  
  return mapping.findForward("success");
 }


만약 ActionForm을 상속한 form객체를 사용하면 위와 같은 방식으로 하되 config.xml파일에서 bean을 DynaActionForm으로 구현 했다면 물론 위의
코드중
InfoFormBean bean = (InfoFormBean) form;
이코드는
DynaActionForm bean = (DynaActionForm)form;

으로 타입 케스팅을 해주어야 캐스팅 에러가 나지 않는다.

Struts 1 - 기본

Published on: 2009. 6. 25. 16:10 by louis.dev



기본 흐름

Client는 주소창에 register.do를 입력을 하면 맨처음으로 web.xml을 로딩한다.

web.xml은

<servlet>
   <servlet-name>action</servlet-name> <!-- 아무이름이나 하면 된다. -->
   <servlet-class>  <!-- 클래스 지정 -->
    org.apache.struts.action.ActionServlet
   </servlet-class>
 
 <init-param> <!-- struct-config.xml 설정 -->
  <param-name>config</param-name> <!-- 이름은 아무거나 -->
  <param-value>/WEB-INF/struts-config.xml</param-value>  <!-- /WEB-INF/(기본베이스 - 다른폴더일때는 경로를 설정해주어야 함)폴더 안에 struts-config.xml파일 위치 지정  - 여기까지 작성후 struts-config.xml파일을 생성-->
 </init-param>
  </servlet>
 
  <servlet-mapping> <!-- url 패턴 설정 -->
   <servlet-name>action</servlet-name> <!-- *.do로 들어오면 servlet-name이 action 실행 -->
   <url-pattern>*.do</url-pattern>
  </servlet-mapping>

다음과 같은 코드로 되어있다.
servlet mapping을 통해서 *.do로 들어오는 모든것들을  ActionServlet을 로드하고 struts-config.xml을 로딩하게 된다.

struts-config.xml은 로딩을 통해서 action 태그에 있는 내용을 로드하게 된다.

ActionServlet은 Servlet에서 init() 메소드의 역할을 하고 RequestProcess 는 service()메소드의 역할을 하게 된다.

RequestProcess에서 RequestProcessor class를 상속받아 다양한 method를 override해서 구현 할 수 있는데

위에 말한 Servlet의 Service() 메소드 역할을 하는것들이 RequestProcessor class의 process*()메소드 이다.

RequestProcessor class에서 process메소드 들을 상속하지 않으면 기본적인 메소드가 실행 된다.

ActionServlet에서 입력된 데이터들은 RequestProcess로 넘어가기 전에 RequestProcessor class 의 processPreprocess()를 오버라이드 함으로서 한글 인코딩 설정을 할 수 있다.

그리고 RequestProcessor class를 선언하고 사용할 때는 반드시 struts-config.xml 파일에서 다음과 같이 선언 해 주어야 한다.

<controller processorClass="com.myhome.info.processor.InfoRequestProcessor" />    //다읨의 경로는 패키지 경로와 클래스 파일 이름이다.

RequestProcess로 넘어온 데이터는 ActionForm에 저장되어 Action class를 상속받은 RegistAction class의 execute() 메소드에서 사용 할 수 있다.

RegistAction class 의 비지니스 로직을 통해 로직을 수행한 후 ActionForward를 통해 ViewPage로 이동을 돕는다. 이 결과값이 다시 RequestProcess로 돌아와 Client에서 뿌려지게 된다.