레이블이 Struts의 Model인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Struts의 Model인 게시물을 표시합니다. 모든 게시물 표시

2013년 8월 8일 목요일

[오라클자바커뮤니티자바교육]struts simple example

Struts의 간단한 예제


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의)  

이번 예제는 간단한 구조를 가지는 프로그램이지만 스트럿츠의 흐름을 이해할 수 있는 예제 입니다.

add.jsp에서 사용자가 두수를 입력한 후 submit 버튼을 누르면 ActionServlet이 호출된 후 AddAction을 호출하여 비즈니스 로직(두수를 더함)을 처리 합니다. 그런 다음 처리 결과를 result.jsp로 포워드 시키는 예제 입니다. 이때 사용자가 입력되는 두수를 저장하기 위해 AddForm이라는 폼빈을 사용했습니다.

이 예제를 실행하기 위해서는 http://struts.apache.org 에 가서 struts 최신 버전인 1.2.4 또는 1.2.6을 다운받습니다. 압축 받은 파일을 풀면 lib 폴더에 jar 파일과 tld 파일이 있는데 jar 파일은 context의 WEB-INF/lib에 위치시키고, tld 파일은 /WEB-INF에 저장 합니다. (전 이클립스를 사용했으며 struts-test라는 Tomcat 프로젝트를 만들었습니다)

Result.jsp에서는 JSTL을 사용했는데 Struts에서 JSTL을 사용하기 위해 http://www.apache.org/dist/jakarta/taglibs/standard/ 에서 jakarta-taglibs-standard-current.zip 파일을 다은 받은 후 jar 파일을 /WEB-INF/lib 폴더에 복사 합니다.


이클립스와 톰캣 플러그인에 대해서는 이전 강좌를 참고하시기 바랍니다.

--------------------
web.xml
--------------------
version="1.0" encoding="ISO-8859-1"?>
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

Welcome to Tomcat

Welcome to Tomcat



/WEB-INF/struts-bean.tld
/WEB-INF/struts-bean.tld


/WEB-INF/struts-html.tld
/WEB-INF/struts-html.tld


/WEB-INF/struts-logic.tld
/WEB-INF/struts-logic.tld




action
org.apache.struts.action.ActionServlet

config
/WEB-INF/struts-config.xml

1 





action
*.do





--------------------
Struts-config.xml
--------------------

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


















path="/FirstAction"
type="add.action.AddAction"
name="addForm"
validate="false"
>







-----------------------------------------------
add.jsp (struts-test 컨텍스트의 루트에 저장)
-----------------------------------------------

최초 실행 시 add.jsp를 localhost/struts-test/add.jsp 라고 호출 합니다.

<%@ page language="java" contentType="text/html;charset=euc-kr" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
:namespace prefix = html />
+=




-----------------------
result.jsp
-----------------------

결과가 포워드 되는 페이지 입니다.

<%@ page language="java" contentType="text/html;charset=euc-kr" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
합은 : :namespace prefix = c />

------------------------
AddAction.java
------------------------

사용자가 submit 버튼을 눌렀을 때 호출되는 action 클래스 입니다.

WEB-INF/src/add/action폴더에 작성 합니다.

package add.action;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import javax.servlet.http.*;
import add.model.AddForm;
import add.model.AddResultVO;

public class AddAction extends Action {
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest req,
HttpServletResponse res) {
int op1 = ((AddForm)form).getOp1();
int op2 = ((AddForm)form).getOp2();

int result = op1 + op2;

AddResultVO vo = new AddResultVO();
vo.setResult(result);

req.setAttribute("resultvo", vo);

//System.out.println(vo.getResult());

return (mapping.findForward("success"));

}
}



-----------------
AddForm.java
-----------------

사용자의 Input Form과 형태를 같이 하며 ActionServlet을 통해 사용자의 입력 값들이 자동으로 저장되는 AddForm 입니다.

WEB-INF/src/add/model에서 작성 합니다.

package add.model;
import org.apache.struts.action.ActionForm;;

public class AddForm extends ActionForm {
protected int op1;
protected int op2;

public int getOp1() {
return op1;
}

public int getOp2() {
return op2;
}

public void setOp1(int op1) {
this.op1 = op1;
}

public void setOp2(int op2) {
this.op2 = op2;
}
}


---------------------
AddResultVO.java
---------------------

결과값을 저장하여 request에 AddResultVO를 저장하여 result.jsp가 나중에 이 값을 이용하여 화면에 출력을 합니다.

WEB-INF/src/add/model에서 작성 합니다.

package add.model;

public class AddResultVO {
private int result;


public int getResult() {
return result;
}

public void setResult(int result) {
this.result = result;
}
}

2013년 8월 5일 월요일

JAVA Struts Model

Struts의 Model 


오라클자바커뮤니티에서 설립한 오엔제이프로그래밍 실무교육센터
(오라클SQL, 튜닝, 힌트,자바프레임워크, 안드로이드, 아이폰, 닷넷 실무전문 강의) 
 www.onjprogramming.co.kr 


스트럿츠에서 모델은 Business Logic을 처리하는 부분과 처리된 결과를 저장 하기 위한 부분으로 나누어 볼 수 있는데 처리된 결과를 저장 하는 빈은 Value Object 또는 DTO라고 부르고 있습니다.

Value Object로 볼 수 있는 DTO(Data Transfer Object)는 대부분 비즈니스 객체를 원격지 뷰에 제공 하는데 사용 합니다.

DTO는 원격 객체의 비즈니스 로직을 표현하지만 비즈니스 로직 안에 있을 필요는 없습니다. 앞의 로그인 예제에서 UserInfoVO.java가 DTO의 역할을 한다고 할 수 있습니다.

DTO를 이용하는 것은 분산 환경에선 거의 필수 이며 네트웍 부하를 줄일 수 있으며 스트럿츠에서 DTO를 사용하는 것은 비즈니스 객체와 프리젠테이션을 분리하며 유지 보수를 용이 하게 합니다.

이전의 로그인 예제를 다시 돌아가 보면 LoginAction에서는 실제 로그인을 처리하는 과정은 포함되어 있지 않습니다. Action 클래스는 Controller의 일부라고 이전에 이야기 했습니다.

Action 클래스에서는 인증 처리를 LoginDAO.java에 위임을 했는데 이렇게 분리 하는 경우 인증 모듈에 변경이 가해 지더라도 Action 클래스에는 영향을 끼치지 않는 것 입니다.

아래 소스 코드를 보도록 하죠…( LoginAction.java)

package login2;

import org.apache.struts.action.Action;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpServletResponse;

import login2.LoginForm;
import login2.Constants;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionError;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionServlet;

/**
 * @author 이종철
 */
public class LoginAction extends Action {
               
        public ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) {
                String id = ((LoginForm)form).getId();
                String pwd = ((LoginForm)form).getPwd();
               
                //Model을 이용하기 이용하여 인증부분의 처리를 합니다.
                LoginDAO loginDAO = new LoginDAO();
                UserInfoVO userinfo = loginDAO.authUser(id, pwd);
               
                //에러 내용을 담을 ActionErrors 객체를 생성
                ActionErrors errors = new ActionErrors();
               
                if (userinfo==null) {
                        //인증 실패                       
                        errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.login.invalid"));                       
                }
                else {
                        //사용자 아이디와 비밀번호가 틀릴경우 비밀번호가 틀리다는 에러 메세지 출력
                        if ( !id.equals(userinfo.getPwd()) ) {
                              errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("error.login.invalid"));
                        }
                }
               
                //로그인 과정에서 에러가 있을 경우 Action클래스의 saveErrors 메소드를 이용해  에러를 저장하고
                //이전의 로그인 페이지로 돌려 보내면 login.jsp의 <html:errors/> 태그에 의해 오류가 출력 돔
                //mapping의 getInputForward()에서 반환하게 되는 정보는 struts-config.xml의 action태그의
                //input 속성에  정의된 페이지로 이동하게 됩니다.
                if (!errors.isEmpty()) {
                    saveErrors(request, errors);
                  return (mapping.getInputForward());
                }       
                               
                //인증 성공한 경우 세션에 LoginInfoVO(로그인한 사용자 정보를 담은 객체)저장
                HttpSession session = request.getSession();
                session.setAttribute(Constants.USER_KEY, userinfo);
               
                //로그를 남기자.
                StringBuffer buf = new StringBuffer("LoginAction : User --> ");
                buf.append(id + "logged in session");
                servlet.log(buf.toString());
                               
                return (mapping.findForward(Constants.SUCCESS));                       
               
        }

       
}

LoginDAO loginDAO = new LoginDAO();
UserInfoVO userinfo = loginDAO.authUser(id, pwd);
이 부분을 보면 LoginDAO의 authUser라는 메소드가 인증을 수행 함을 알 수 있는데…
실행 후 결과를 리턴 하는 부분을 보면 USerInfoVO라는 DTO(Data Transfer Object)를 리턴함을 알 수 있습니다.

LoginDAO는 비즈니스 로직을 수행하는데(인증처리), 이 처리가 정상적으로 된 경우 사용자 정보(UserInfoVO)를 어디엔가 저장 해 두고 (ID와 PWD이외의 정보가 DB에서 읽혀져서 포함 될 수 있습니다.) 나중에 VIEW에서도 꺼내 볼 수 있는데 이때 UserInfoVO 빈이 DTO or Value Object가 됨을 알 수 있습니다.

이 USerInfoVO는 LoginAction에서 인증 결과가 성공 이었음을 확인 후 session에 setAttribute로 저장 됩니다.

//인증이 성공한 경우 세션에 UserInfoVO(로그인한 사용자 정보를 담은 객체)저장
HttpSession session = request.getSession();
session.setAttribute(Constants.USER_KEY, userinfo);



아래는 LoginDAO.java 파일의 내용 입니다.

package login2;

public class LoginDAO {
       
        public UserInfoVO authUser(String id, String pwd) {
                /**
                * 이부분은 실제 DB에서 ID와 PASWORD로 인증을 해야 하는 부분 입니다.
                * 예제를 간략히 하기 위해 이부분의 처리는 생략 했으며 ID가 "jclee", Password가 "jclee" 인 경우엔
                * 인증을 허용 합니다.
                */
               
                if ( id.equals("jclee")&& pwd.equals("jclee")) {
                        //ID:jclee, PASSWORD:jclee인 경우 인증이 성공, 사용자의 정보(아이디, 패스워드)를 저장 합니다.
                        return new UserInfoVO(id, pwd);
                } else {
                        return null;
                }               
        }
}


아래는 DTO인 UserInfoVO.java 입니다.

package login2;
/**
 * 로그인이 정상적으로 이루어진 경우 사용자의 정보 등을 저장 하는 빈
 * 본 예제에서는 ID와 PASSWORD를 저장 합니다.
 */
public class UserInfoVO {
        private String id = null;
        private String pwd = null;
       
        //LoginDAO에서 인증이 성공인 경우 아래의 생성자를 불러 값을 setting 합니다.
        public UserInfoVO(String id, String pwd){
                this.id = id;
                this.pwd = pwd;
        }
       
        public  String getId() {
                return id;
        }

        public  String getPwd() {
                return pwd;
        }
}


다음은 VIEW쪽에서 세션에 저장 되어 있는 UserInfoVO 빈을 이용하는 예 입니다.
<body>               
            <h3>반갑습니다.<bean:write name="user" property="id"/>님!</h3>       
                <ul>                       
                        <li>                           
                                <html:link forward="logoff">로그아웃</html:link>
                        </li>                       
                </ul>
        <body>