상세 컨텐츠

본문 제목

Jakarta Struts Getting Started

프로그래밍/JAVA

by 라제폰 2009. 3. 6. 19:16

본문

Jakarta Struts 강좌 1

Summary : 새로운 개발 방식으로 대두되고 있는 Model 2개발방식을 지원하는 대표적인 프레임워크인 Jakarta Struts에 대하여 살펴본다. Jakarta Struts의 내용이 워낙 방대하기 때문에 이번 강좌는 Jakarta Struts의 설치부터 시작하여 Jakarta Struts에 대한 간단한 예제를 통하여 Jakarta Struts이 무엇인지에 대하여 간략하게 살펴본다. 이번 강좌의 목적은 Jakarta Struts의 설치를 이해하고, 간단한 예제를 통하여 Jakarta Struts가 어떻게 구현되는지 이해하는데 있다.

Jakarta Struts 설치하기

웹의 초창기에는 HTML만을 이용하여 다양한 페이지를 표현하는 것이 가능했다. 사이트 규모가 현재보다 작았으며, 웹으로 동적인 페이지를 구현하려는 요구사항도 많지 않았다. 점차 웹이 발전하면서 동적인 페이지를 요구하게 되었으며, 그와 발맞추어 JSP, ASP등을 이용하여 동적인 페이지의 개발이 가능해졌다.

웹 환경에서 개발 경험이 많지 않았던 개발자들은 JSP, ASP내에서 대부분의 로직을 구현하는 Model 1방식을 이용하여 개발하는 것이 국내 웹 개발의 주가 되었다. 아직까지도 웹 개발에 가장 많이 사용되는 개발 방식은 Model 1방식이다. 그러나 점차 웹에서 많은 기능을 구현하기를 클라이언트들이 요구하고 있으며, 대규모의 사이트의 프로젝트들이 Model 1만으로 해결하기 어려운 경우가 많아지게 되었다.

따라서 Model 1의 대안으로 나온 개발방식이 Model 2개발방식이다. 그러나 Model 2방식은 개념을 잡고 구현하기가 Model 1방식보다 더 어려우며, Model 2방식으로 처음 개발하는 독자들은 더 많은 시간을 요하게 되었다. 따라서 Model 2방식을 좀 더 적은 시간에 효율적으로 개발이 가능하도록 하기 위하여 프레임워크화하는 프로젝트가 진행되게 되었다. 그 중에서 가장 주목을 받고 있는 것이 Jakarta 프로젝트 중의 Struts프레임워크이다.

이번 강좌에서는 Struts프레임워크를 설치하는 과정과 간단한 예제를 통하여 Struts프레임워크가 구현되는 방법에 대하여 살펴보는데 있다.

Struts내부적으로 각각의 예제가 구현되는 원리는 계속되는 강좌를 통하여 이해하면 되기 때문에 처음부터 너무 많은 것을 이해하려고 노력하지 않아도 된다.

이번 강좌의 간단한 예제를 실제로 테스트해보면서 "기존과 다른 웹 개발 방법이구나h2."하고 느끼면 될 것으로 생각한다. 개발자들이 Struts에 대하여 호기심을 가질 수 있도록 만드는 것이 이번 강좌의 가장 큰 목적이다. 서두가 너무 길었다. Struts 설치 방법 및 예제를 만들어 보자.

  • 1. Struts베타버전이 나온지 너무 오래되었기 때문에 이번 예제에서 사용할 Struts버전은 야간빌드(Nightly Builds)버전을 사용할 것이다. http://jakarta.apache.org/builds/jakarta-struts/nightly/ 에 접근하여 가장 최근에 빌드한 버전을 다운 받는다. 강좌를 진행하고 있는 현재 가장 최근 버전은 jakarta-struts-20021217.zip이다. 예상보다 상당히 큼을 알 수 있다.
  • 2. 다운 받은 야간 빌드파일을 개발자들이 원하는 위치에 압축을 푼다. 압축을 풀면 Struts에서 사용하는 jar파일을 포함하고 있는 lib디렉토리와 다양한 웹 애플리케이션을 포함하고 있는 webapps디렉토리가 있음을 알 수 있다. webapps에는 총 8개의 war파일이 있다. 각각의 파일은 Struts를 공부하는데 많은 도움이 되기 때문에 Struts를 공부하는 개발자들은 이 8개를 분석해도 많은 도움이 될 것이다. 그 중에서 struts-documentation.war는 Struts관련한 모든 문서(API포함)를 포함하고 있기 때문에 꼭 살펴보는 것이 좋을 것으로 생각된다.
  • 3. Struts는 애플리케이션 서버 위에서 사용할 수 있기 때문에 개발자들이 테스트하고자 하는 서버가 설치되어 있어야 한다. 이번 강좌에서는 Tomcat서버를 이용할 것이다. Tomcat의 버전은 가능하면 3.3이상에서 테스트하는 것이 좋다. 이유는 XML파서의 버전 때문이다. Tomcat서버의 설치에 관한 문서는 웹에 많기 때문에 이번 강좌에서는 제외시킨다. Tomcat 3.3 이상이 설치되어 있다는 가정하에 이번 강좌를 계속하여 진행한다. 필자가 이번 강좌에 사용한 Tomcat 버전은 4.6이다.
  • 4. Struts예제를 테스트해볼 새로운 애플리케이션을 생성한다. 새로운 애플리케이션을 생성하는 방법은 "Tomcat설치 디렉토리 >> webapps"아래에 자신이 만들고자 하는 애플리케이션 이름을 가진 디렉토리를 생성한다. 이번 강좌에서 사용할 애플리케이션은 zigistruts로 진행한다.
  • 5. zigistruts아래에 WEB-INF를 생성한다. WEB-INF디렉토리 밑에 lib와 classes디렉토리를 생성한다. 또한 필자는 소스와 클래스파일을 분리하기 위하여 WEB-INF아래에 src디렉토리를 생성한다. 소스와 클래스 파일을 분리하여 관리하는데 익숙하지 않은 개발자들은 IDE를 이용하면 쉽게 할 수 있다. 필자는 Eclipse를 이용하였다. Eclipse에 대한 자세한 내용은 http://www.eclipse.org를 참조하기 바란다.
  • 6. 이번 강좌에서 사용할 JSP파일을 관리하기 위하여 zigistruts디렉토리 밑에 struts1 디렉토리를 생성한다. 지금까지 생성한 디렉토리 구조를 살펴보면 다음과 같다.

  • 7. Tomcat설치디렉토리\webapps\ROOT\WEB-INF에서 빈 web.xml을 zigistruts\WEB-INF에 복사한다.
  • 8. 압축을 푼 Struts lib디렉토리 아래에 있는 모든 jar파일을 zigistruts\WEB-INF\lib에 복사한다.
  • 9. 압축을 푼 Struts lib디렉토리 아래에 확장자가 tld인 모든 파일을 zigistruts\WEB-INF에 복사한다. tld는 struts에서 제공하는 커스텀 태그를 이용하기 위한 것이다. 커스텀 태그에 익숙하지 않은 독자들은 JSP관련 책을 참고하기 바란다.

*10. zigistruts\WEB-INF아래에 struts-config.xml의 이름을 가지는 XML파일을 생성한다. 이상으로 Struts를 테스트하기 위한 기본적인 환경은 모두 갖추어졌다. 지금까지 설치한 파일들을 채워가면서 Struts예제를 실행해보도록 하겠다. 지금까지 설치한 모든 파일들의 구조는 다음 그림과 같다.

Struts 커스텀 태그를 이용하여 JSP만들기

첫번째 예제는 Struts에서 제공하는 커스텀 태그를 이용하여 JSP페이지를 생성해보도록 하겠다. Struts의 커스템 태그를 사용하기 위해서 web.xml을 다음과 같이 설정한다. web.xml의 내용을 보면 알겠지만 모든 커스텀 태그를 사용하지 않고 기본적인 커스텀 태그만을 사용하였다.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> <web-app> <!-- Struts Tag Library Descriptors --> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> </web-app>

Struts의 커스텀 태그를 이용하는 간단한 JSP파일을 생성한다.

<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html> <head> <title>내가 만드는 첫번째 Struts application!</title> <html:base/> </head> <body> 이 페이지는 내가 만든 첫번째 Struts Application페이지이다.h2.! </body> </html:html>

Struts의 Resource Bundle을 이용하여 JSP 메세지 처리하기

Struts는 Resource Bundle을 이용하여 JSP의 메세지를 쉽게 처리할 수 있다. Resource Bundle이란 자바에서 흔히 사용하는 Properties파일에 JSP의 메세지나 에러 메세지들을 처리하는 경우 손쉽게 사용이 가능하도록 하였다. 이번 예제는 Properties파일에 메세지를 저장한 후에 JSP에서 메세지를 사용할 수 있도록 하는 예제를 만들어본다.

이 예제를 테스트해보기 위해서는 먼저 Properties파일을 생성해야 한다. 이번 강좌에서 사용한 Properties파일의 위치는 WEB-INF\classes\net\javajigi\tutorial을 기본 디렉토리로 한다. 이 디렉토리에 MessageResources.properties파일을 만든다.

생성한 properties파일을 Struts가 사용하기 위해서 web.xml과 struts-config.xml을 다음과 같이 설정한다.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"  "http://java.sun.com/j2ee/dtds/web-app_2_3.dtd"> <web-app> <!-- Action Servlet Configuration --> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!-- Resources bundle base class --> <init-param> <param-name>application</param-name> <param-value>net.javajigi.tutorial.MessageResources</param-value> </init-param> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>3</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>3</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- Action Servlet Mapping --> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- Struts Tag Library Descriptors --> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> </web-app>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"  "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config> <data-sources /> <form-beans /> <global-exceptions /> <global-forwards /> <action-mappings /> <controller /> <message-resources parameter="net.javajigi.tutorial.MessageResources" /> </struts-config>

web.xml에 대해서는 대부분의 개발자들이 알 것으로 예상된다. 하지만 struts-config.xml에 대하여 생소한 개발자들이 많을 것으로 예상되어 간단하게 설명한다. struts-config.xml은 Struts프레임워크에서 사용하는 모든 설정 정보를 담고 있는 파일이라고 생각하면 된다. 그 이상에 대한 설명은 다음 강좌에 계속해서 다루도록 하겠다.

MessageResources.properties에 다음과 같이 두개의 메세지를 생성한다.

zigi2.title = 내가 만드는 첫번째 Struts application!

zigi2.text1 = 이 페이지는 내가 만든 첫번째 Struts Application페이지이다.h2.!

Properties파일이 그렇듯이 key = value 쌍으로 가진다. 위에서 생성한 두개의 메세지는 zigi1.jsp에서 title과 본문에서 사용한 메세지들을 담고 있다. Properties파일에 저장되어 있는 메세지를 JSP에서 사용하는 JSP를 생성해본다.

<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html locale="true"> <head> <title><bean:message key="zigi2.title" /></title> <html:base/> </head> <body> <bean:message key="zigi2.text1" /> </body> </html:html>

zigi2.jsp내부를 보면 message태그를 이용하여 Properties파일을 이용하고 있다. message태그의 키값을 통하여 Properties에서 메세지를 쉽게 가져올 수 있다. JSP나 에레 메세지를 Properties로 분리하는 장점은 계속되는 강좌를 통하여 확인할 수 있을 것이다.

Struts의 Controller기능을 이용하는 예제

지금까지는 Struts에서 제공하는 커스텀 태그를 이용하여 간단하게 JSP를 생성하는 예제와 Properties파일에서 메세지를 쉽게 얻어올 수 있는 방법에 대하여 살펴보았다. 이 부분은 Struts의 View에 해당하는 부분이라고 할 수 있다.

이 절에서 다루는 내용은 Struts의 핵심적인 내용이라고 할 수 있는 Controller기능에 해당하는 예제를 살펴볼 것이다. 기존의 개발 방식과 달라 생소하게 생각하는 개발자들이 많을 것이다. 그리고 생성할 파일들이 기존 개발방식보다 많기 때문에 복잡하게 생각하는 개발자들이 많을 것으로 예상한다. 하지만 이번 강좌의 목적이 Struts에 대하여 간략하게 살펴보는 것이기 때문에 세부 항목에 대하여 이해하지 못해도 걱정하지 말기 바란다. 계속되는 강좌를 통하여 세부 항목에 대하여 살펴볼 것이다.

각 예제에 대한 세부적인 설명 없이 예제소스와 결과화면을 통하여 Struts를 이용하여 개발되는 과정을 간략하게 살펴보자. 여기서 살펴볼 예제는 웹 개발시 많이 개발되는 로그인 과정을 Struts를 이용하여 개발해보도록 하겠다.

먼저 아이디와 비밀번호를 입력할 수 있는 입력폼을 생성해보자.

<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html locale="true"> <head> <title><bean:message key="login.title" /></title> <html:base/> </head> <body> <html:form action="/login"> <bean:message key="prompt.id" /> <html:text property="id" /> <br /> <bean:message key="prompt.password" /> <html:password property="password" /> <br /> <html:submit> <bean:message key="login.login" /> </html:submit> </html:form> </body> </html:html>

위 login.jsp내부를 보면 Struts의 다양한 태그를 사용하고 있다.

<html:form action=> 태그는 <form>태그

<html:text property=> 태그는 <input type="text">태그

<html:password property=> 태그는 <input type="password"> 태그

<html:submit> 태그는 <input type="submit"> 태그와 같은 역할을 한다.

login.jsp에서 사용한 메세지를 위하여 MessageResources.properties에 다음과 같이 4개의 메세지를 추가하여야 한다.

login.title = Welcome to RegisterUser

login.login = 로그인

prompt.id=ID :

prompt.password=Password :

Struts를 이용하여 위에서 생성한 Login.jsp의 submit이 실행되었을 때 ID와 Password가 맞았는지 확인하는 처리를 위하여 두개의 클래스를 생성해야 한다.

첫번째 클래스는 ActionForm클래스를 상속하는 클래스로 Login.jsp에서 전달되는 ID와 Password 인자를 저장하게될 클래스이다. 두번째 클래스는 Action클래스를 상속하는 클래스로 실질적인 login의 실질적인 처리를 담당하는 클래스이다.

package net.javajigi.tutorial.form; import javax.servlet.http.HttpServletRequest; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionMapping; public class LoginForm extends ActionForm { /** password property */ private String password; /** id property */ private String id; public ActionErrors validate( ActionMapping mapping, HttpServletRequest request) { throw new UnsupportedOperationException("Generated method 'validate(...)' not implemented."); } public void reset(ActionMapping mapping, HttpServletRequest request) { password = ""; id = ""; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getId() { return id; } public void setId(String id) { this.id = id; } }
package net.javajigi.tutorial.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.javajigi.tutorial.form.LoginForm; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; public class LoginAction extends Action { public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return(mapping.findForward("mainmenu")); } }

LoginAction파일은 Action클래스를 상속한다. Action클래스의 execute()를 오버라이드한다. 실질적인 로그인 작업의 성공여부에 대한 로직은 execute()내에서 실행되게 된다. 위 예제에서는 단순히 mainmenu로 매핑되어 있는 URL로 Forword하고 있다. mainmenu에 해당하는 JSP를 간단하게 생성해본다.

<%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %> <html:html locale="true"> <head> <title><bean:message key="mainmenu.title" /></title> <html:base/> </head> <body> <bean:message key="mainmenu.presentation" /> </body> </html:html>

mainmenu.title=Main Menu

mainmenu.presentation=이 페이지는 Main Menuh2.

이상으로 로그인 과정을 간단하게 테스트할 모든 파일들이 생성되었다. 기존방식보다 상당히 복잡함을 알 수 있다. 그러나 여기서 그치는 것이 아니라 지금까지 생성한 파일을 struts-config.xml에서 설정해주어야 한다. 지금까지 생성한 파일을 struts-config.xml에서 설정한 파일은 다음과 같다.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"  "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config> <!-- ========== Data Source Configuration =============================== --> <data-sources /> <!-- ========== Form Bean Definitions ================================== --> <form-beans type="org.apache.struts.action.ActionFormBean"> <form-bean name="loginForm" type="net.javajigi.tutorial.form.LoginForm"> <form-property name="password" type="java.lang.String" /> <form-property name="id" type="java.lang.String" /> </form-bean> </form-beans> <!-- ========== Global Exception Definitions ============================== --> <global-exceptions /> <!-- ========== Global Forward Definitions =============================== --> <global-forwards type="org.apache.struts.action.ActionForward"> <forward name="mainmenu" path="/struts1/mainmenu.jsp" /> </global-forwards> <!-- ========== Action Mapping Definitions =============================== --> <action-mappings type="org.apache.struts.action.ActionMapping"> <action attribute="loginForm" input="/struts1/login.jsp" name="loginForm" path="/login" type="net.javajigi.tutorial.action.LoginAction" validate="true" /> </action-mappings> <!-- ========== Controller Configuration ================================ --> <controller /> <!-- ========== Message Resources Definitions ============================ --> <message-resources parameter="net.javajigi.tutorial.MessageResources" /> <!-- ========== Plug Ins Configuration ================================= --> </struts-config>

위 LoginAction파일에서 수행한 작업이 없기 때문에 로그인 화면에서 로그인을 실행할 경우 바로 mainmenu페이지로 이동한다. 다음 예제는 이 예제를 바탕으로 좀 더 발전시켜 실질적으로 로그인이 되었는지 확인해 보도록 하겠다. 로그인이 실패할 경우 에러메세지를 출력함을 알 수 있을 것이다.

발전된 로그인 예제

지금까지 간단한 로그인 예제를 살펴보았다. 그러나 실질적인 로그인 과정을 처리하는 부분은 없었기 때문에 Struts에 대하여 깊이 있게 이해하기는 힘들었을 것이다. 따라서 로그인 과정을 처리하는 부분을 JSP에서 수행하지 않고 클래스에서 어떻게 처리하는지, 에러가 발생할 경우 처리하는 과정에 대하여 살펴본다.

LoginForm의 validate메써드에 아이디와 비밀번호를 고정하여 아이디와 비밀번호가 틀릴경우 에러메세지를 출력하도록 하였다.

public ActionErrors validate( ActionMapping mapping, HttpServletRequest request) { if (id.equals("javajigi") && password.equals("password")) return null; else { ActionErrors errors = new ActionErrors(); errors.add("login", new ActionError("error.login")); return errors; } }

validate 메써드 내부를 보면 ActionError("error.login")와 같이 에러 메세지를 사용하고 있음을 알 수 있다. 에러 메세지 또한 Properties에 넣어서 출력하는 것이 가능하다.

error.login=로그인 실패. 아이다와 비밀번호를 확인후 다시 입력하십시요.

에러메세지를 좀 더 세련되게 보여주기 위해서 다음과 같은 형식으로 MessageResources.properties에 추가해보자.

errors.header=<h3><font color="red">Validation Error</font></h3>
You must correct the following error(s) before proceeding:<UL>
errors.footer=</ul><hr>

로그인 실행시 에러가 생길 경우 에러처리를 위하여 login.jsp의 <body>태그내에 다음과 같은 태그를 사용하면 된다.

<html:errors />

위와 같이 간단하게 수정한 다음 아이디와 비밀번호가 틀리도록 하여 로그인 과정을 실행해본다. 에러가 발생함을 볼 수 있다. 아이디와 비밀번호가 맞을 경우 처음과 같이 mainmenu페이지로 이동한다.

지금까지 Struts 프레임 워크를 이용하여 로그인 과정을 수행하는 간단한 예제를 살펴보았다. Struts는 상당히 방대한 프레임워크이기 때문에 한번에 모두 이해하기는 힘들다. 따라서 이번 강좌에서는 간단하게 실행하는 과정만을 살펴보았다.

첫강좌에서 이해하지 못하는 부분이 대부분이라고 생각한다. Struts 사용하기 너무 어렵다고 속단하지는 말기 바란다. 앞으로 계속되는 강좌를 통하여 점진적으로 공부한다면 어떠한 개발방식보다 더 간단하다는 것을 알 수 있을 것이다.

다음 강좌에서는 이번 강좌에서 다룬 내용들에 대하여 하나씩 뽑아서 자세하게 살펴보도록 하겠다.

참고 자료

관련글 더보기