Struts1의 다양한 Action들


struts-extras-1.3.8.jar에서 지원하며 다양한 액션을 구현 할 수 있다.

■ Action 상속 관계도



1. ForwardAction



 struts-config.xml 의 ActionMapping에서 action 요소에 parameter 속성으로 지정한 URL로 forward 하게 된다. 직접 해당 URL을 호출하면 RequestProcessor을 통해 바로 View page로 이동하지만
ForwardAction을 사용하게 되면 스트럿츠 컨트롤러 서블릿의 기능(폼 빈의 처리 등)을 사용 할 수 있다는 장점이 있다.

<!--직접 해당 URL 호출-->
<action path="/info/index" forward="/info/register.jsp"/>

<!-- ForwardAction을 사용해서 ViewPage요청 -->
<action path="/info/index"
            type=“org.apache.struts.actions.ForwardAction”
            parameter="/info/register.jsp” />


2. IncludeAction.

 

 ForwardAction과 동일한 방식이며 비즈니스 로직에서 처리 후 RequestProcessor로 진입하지 않고 바로 페이지로 이동한다. View page로의 빠른 이동이 가능하다는 장점이 있지만, Request Prcessor를 통과 하지 않기 때문에 page Encoding,validator 등 을 사용할 수 없다.

<!-- IncludeActiond 사용 -->
<action path="/index"
type = "org.apache.struts.actions.IncludeAction"
parameter = "/info/register.jsp"/>

3. DispatchAction

 하나의 Action에서 두개 이상의 ActionForward를 구현할 때 사용된다.


 JSP form 페이지에서 name이 struts-config.xml 에서 설정해논 parameter의 이름과 일치해야 실행된다.

- struts-config.xml

.... 생략 ....

    <action-mappings>
   
   <action path = "/dispatchIndex"
    type = "org.apache.struts.actions.ForwardAction"
    parameter = "/dispatch/register.jsp"/>
    
  <!-- unknow 은 input 속성을 대체하기 위한 속성이다. 입력 폼이 여러개 발생할 때 사용된다.  -->
  <action path = "/dispatch"
    name = "bean"
    scope = "request"
    unknown = "true"
    parameter = "method"
    type = "com.myhome.dispatch.InfoDispatchAction">
    
<!-- forward 이름이 메소드 마다 달라야 한다 -->
   <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>

.... 생략 ....

- InfoDispatchAction .java

//하나의 Action에서 여러개의 action을 구현했다.

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.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());
 }
 
}


자세한 내용은 파일을 참조한다.





'FrameWork > Struts1' 카테고리의 다른 글

Struts1 FileDownload  (0) 2009.08.18
Struts1 fileUpload  (0) 2009.08.18
Struts1의 Action 4  (0) 2009.08.16
Struts1의 Action 3  (0) 2009.08.16
Struts1의 Action 2  (0) 2009.08.12
Struts1에서 ActionForm 사용하기.  (0) 2009.07.25
Struts1 에서 iBatis 사용하기  (0) 2009.07.05
Struts 1 을 사용하여 간단한 회원가입, 리스트 불러오기.  (0) 2009.07.05
Struts1 개발환경 설정.  (0) 2009.07.05
Struts(스트럿츠) 란?  (0) 2009.06.27

■ 기본 환경 설정.

1. library 파일 추가.

 
apache 사이트의 struts에서 다운로드. 여기서는 2.0.14 버전을 사용한다. 공부용으로 사용하기 위해 Full Distribution을 다운로드 한다.

 다운로드한 파일에서 struts-2.0.14\apps\ 들어가면 struts2-blank-2.0.14.war 파일이 존재 한다. 이 파일은 예제파일로 이것을 기본으로 작업을 수행 할 수 있도록 제동된 파일이다. 이것을 압출해제 하면 struts2-blank-2.0.14\WEB-INF\lib 안에 들어있는 파일 들을 eclipse에서 생성한 프로젝트의 lib 폴더에 복사해서 사용한다.

2. web.xml 파일 설정

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

<filter-mapping>
   <filter-name>struts2</filter-name>
   <url-pattern>/*</url-pattern>//여기서는 확장자를 기록할 수 없다. 인터센터로부터 사전에 알려줄 수 있다.
</filter-mapping>


* filter-name은 위에서 설정한 filter-name과 같아야 한다. url-pattern에는 다른 확장자를 사용할 수 없으면 /*가 default다. 다른 확장자는 struts.properties에서 설정 할 수 있다.

3. struts.properites 파일 생성

 메모장을 사용하여 struts.properites 파일을 만들고 eclipse의 navigator 탭에서 src 폴더로 복사하면 자동적으로 build의 classes 폴더에 생긴다.
 설정파일들을 classes 폴더에서 찾기 때문에 확인해야 한다. 작업을 하다면 많은 xml 설정 파일들을 src 폴더에 만드는데, src 폴더에 만들면 자동적으로 들어가므로 확인만 하면 된다.

 struts.properites은 Interceptor로 부터 적용할 각각의 constant(상수)만 정의한다.

struts.enable.DynamicMethodInvocation=true
struts.i18n.reload=true //개발자 디버그 모드 설정
struts.devMode=true
struts.configuration.xml.reload=true // configuration에서 설정된 모든 xml 다시 로딩해해서 무조건 처리해라. 실무에서는 사용 금지!!
struts.custom.i18n.resources=globalMessages
struts.url.http.port=8989 //was의 포트 번호, default는 80
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 // do, action, bit 확장자로 올때 접근 허용, default는 action
struts.i18n.encoding=euc-kr //ednoding 타입이 들어올때 euc-kr로 들어온다


4. struts.xml 파일 생성.

 struts.xml은 맵핑 역할을 한다. 각각의 모듈에서 작업했던 xml을 연결하는 역할만 한다. 설정을 include 시키기만 하면 된다.
 
※ struts.xml 에다가 Interceptor를 적용해도 된다. 여기다가 적용하려면 tag로, struts.properites로 적용하려면 상수로. 둘중에 아무곳에 한군데만 적용해주면 된다. 그러나 struts.xml 에다가 모두 적용을 하면 복잡하기 때문에 Interceptor 적용할 상수 정의는 struts.properites로 빼고 struts.xml에는 include만 한다.

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

5. struts.xml에 include 할 mapping 문서 만들기.(ex. info.xml)

  <package name="info" namespace="/" 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">
<!-- execute가 default이며 다른 method라면 무조건 써야된다-->
      <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> 
<!-- success 대문자 쓰면 에러 난다. -->
     </action>

    <action name="update"
           class="com.myhome.info.actions.InfoUpdateAction">
      <result name="success" type="redirect">list.action</result>
    </action> 
    
    </package>
   
</struts>

* 여기서 패키지를 직접 잡는다. spring에서 ViewResolver라고하고, 여기서 prefix와 suffix를 잡는다. 패키지 네임을 유일한 값을 설정해야 한다.

 namespace는 프로젝트 이름이 struts2이면 http:localhost:8989/struts2/ 여기 다음부터 나오는게 namespace 다. 현재 context에서 바로 파일로 들어가면 그냥 namespace="/" 하면되고, http:localhost:8989/struts2/info/index.action 으로 들어가고 싶으면 namespace="/info" 로 설정하면 index.action 으로 들어온다. index.action으로 들어오면 action name 과 같은 곳을 실행한다.

 action name은 한 xml 문서 내에서 중복되면 안되며, url pattern과 같은 이름이 들어오면 class="" 에 지정된 action이 실행된다. method="execute"는 class에서 지정된 파일안에 execute method를 실행시킨다.

 result name은 action class에서 return 값으로 설정해 놓은 값고 일치하면 result 에 지정해 놓은 jsp 파일로 값들을 전달하며, 페이지 이동을 한다. class 팔에서 return SUCCESS;은 대문자이지만 여기서는 꼭!! 소문자 success로 써야 한다.

 result type에서
<result type="chain">list<result>
//action의 name이 list인 곳으로 가라 - 또 다른 액션으로 데이타와 같이 보낸다. 기존에 있는 액션 이름을 찾아 간다.
<result type="redirect">list.action<result>
//다른 액션으로 데이타 없이 보낼 때
<result type="dispatcher">/WEB-INF/info/list.action<result>
//type의 default 값이다. 전체 경로를 써줘야 한다.

+ 추가 설명 : Action process model


- 액션은 하나의 작업 단위이며 URL이다.
- 액션은 하나의 클래스 또는 메소드이다.
- 액션은 한 종류의 비즈니스 로직을 수행하기 위한 통로이다.
- 액션은 struts.xml 에서 정의된다.
- 액션 메소드는 하나의 토큰 스트링을 반환한다.
- 액션체인 : 액션을 수행한 결과로서 다른 액션을 호출할 수 있다.
- 액션의 프로퍼티는 태그와 매핑할 수 있다.



■ 구현하기(환경설정 작업에 이어서)

구현순서(절대적인 방법은 아님!) : 위에 환경설정 ->  JSP파일 만들기 -> Class 생성(**Actions 패키지와 **action.java 파일 만들기) -> mapping 문서 만들기(struts-2.0.14\apps\struts2-blank-2.0.14\WEB-INF\classes 안에 있는 example.xml 파일에서 복사 해서 사용) -> struts.xml 파일에 include. -> iBaits 설정을 위한 Package, Class와 xml 만들기 SQLManager.java, SqlMapConfig.xml, SqlMap.xml 파일 만들기 -> **VO.java 만들기(VO에서 바로 DB로 넣는다) -> **DAO.java 만들기 -> **.jsp 에서 데이터 주고, 받기 설정하기.

▶ 구현하기 위한 추가 설명

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

@SuppressWarnings("serial")
public class InfoRegisterAction extends ActionSupport{
 
 /*form property fields*/
 private InfoVO bean;

 @Override
 public String execute() throws Exception {
  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;
 }
}

2. jsp 페이지 만들기.(register.jsp)
<%@ page contentType="text/html;charset=euc-kr"%>
<!--  모든 파라미터를 하나의 객체로 받기 위해 선언한다. 데이터를 객체로 받기 위해 bean 생성-->
<%@ taglib prefix="s" uri="/struts-tags" %>
<s:bean id="bean" name="com.myhome.info.vo.InfoVO"/>
<html>
  <head>
... 생략 ....
    <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> 

 *  <%@ taglib prefix="s" uri="/struts-tags" %>에서 struts2에서 prefix는 s 만 받는다.
 
 <s:bean id="bean" name="com.myhome.info.vo.InfoVO"/> s:bean 태그로 bean객체를 설정해 놓고, name을 그에 맞는 property로 지정해 놓으면 자동적으로 bean에 데이터들이 들어가게 된다. 

 이렇게 입력된 데이터는 ActionSupport를 상속한 Action Class로 이동하고, Class 에서 private InfoVO bean; 을 설정하고, setter, getter를 설정해 놓으면, setter를 통해 데이터를 저장하고, getter를 통해 데이터를 jsp 페이지로 보낸다.

여기서 중요한 것은 Action Class에서
private InfoVO bean; 설정한 이름 bean과 jsp 에서 설정한 <s:bean id="bean" name="com.myhome.info.vo.InfoVO"/> bean의 id이름인 bean과 결과페이지인 jsp 페이지에서의
<s:bean id="bean" name="com.myhome.info.vo.InfoVO"/> bean의 id이름인 bean 이름이 같아야 한다.

3. struts2 태그.(list.jsp)

<s:iterator value="list">  
      <tr bgcolor="#ffffff">
       <td align="center">
        <s:property value="num"/>
       </td>
       <td align="center"><a href="javascript:query('${num }')">${name }</a></td>
       <td align="center">${sex }</td>
       <td align="center">${tel }</td>
       <td align="center">${wdate }</td> 
      </tr>
   </s:iterator>  

 Action Class에서 return 값으로 list가 넘어왔을 경우에 foreach 태그 대신에 iterator 을 사용할 수 있다.

 <s:property value="num"/> property 이름으로 바로 접근 할 수 있는 태그.

Struts2 기본 환경 설정 및 구현 끝!

 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의 기본적인 작동원리 끝!

Struts 2 는 무엇인가?

 WebWork + Struts 가 합쳐진게 Struts 2 이다.


http://struts.apache.org/


 WebWork는 View Framework 로서 유명하고, 이를 기반으로 WebWork Framework와 Struts Framework가 합쳐져 Struts 2가 탄생.

 Struts 1과 Struts 2는 다르며, 그 이유중 하나는 WebWork의 인터셉터(Interceptor)라는 개념이 들어가 있다.


 인터셉터는 HttpRequest를 중간에서 가로채는 Filter와 비슷한 개념이나, Action 전 후에 다른 처리를 할 수 있다. 인터셉터는 AOP(aspect-oriented programming) 개념으로 생각하면 된다고 한다.

 그외에 의존성주입(Dependency Injection)을 지원하고, 다양한 Plugin(JFreeChard, Sitemesh 등), Result 타입을 지원한다.

간단한 Struts2 소개 끝!

더 자세한 내용은

http://wiki.dev.daewoobrenic.co.kr/mediawiki/index.php/Struts_basic

여기서.



+ Recent posts