스트러츠는 JSP의 모델2를 구현한 프레임워크이다. 현재는 스트러츠2로 새로이 바뀌었지만 관공서 등 기존 작성된 대부분의 프로젝트는 스트러츠1을 기반으로 작성된 것이 많으므로 스트러츠1을 기반으로 한 예제를 만들어 보려고 한다.

예제에 사용된 환경은 다음과 같다.

  • Tomcat 6.0.20
  • JSTL 1.2
  • Struts 1.3.10
  • Eclipse 3.5
  • MySQL 5.1

예제를 단순화시키기 위해 게시판은 기본적인 구조를 가지도록 스키마를 작성했다.

스키마는 JSP 모델1과 동일하다.

이클립스에서 실행시키기 위해 Struts 1.3 라이브러리를 프로젝트의 lib 폴더로 옮겨놓는다. 참고를 위해 프로젝트 탐색기의 구조를 캡쳐해서 올려놓았다.

스트러츠1은 입력폼(writeForm.jsp)과 입력폼의 데이터를 검증하기 위한 액션 폼(InsertForm.java), 그리고 입력폼의 데이터를 모델로 전달하는 액션(InsertAction.java)을 구현한다. 그리고 struts-config.xml을 통해 액션 폼과 폼, 액션을 연결하여 컨트롤러가 실행하도록 한다. 물론 컨드롤러의 배포기술자는 web.xml에 작성한다.

입력폼(writerForm.jsp) 소스

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
	"http://www.w3.org/TR/html4/loose.dtd">
<html:html lang="true">
<head>
<title><bean:message key="writeform.title"/></title>
<html:base/>
<link href="${pageContext.request.contextPath}/bboard/css/writeForm.css"
	rel="stylesheet" type="text/css">
</head>
<body>
<h1><bean:message key="writeform.title"/></h1>
<html:form method="post" action="insert" lang="UTF-8" focus="title">
<table border="1">
<colgroup>
<col class="tableHeader">
<col>
</colgroup>
<tr>
<td colspan="2"><html:errors/></td>
</tr>
<tr>
<th><bean:message key="writeform.form.title"/></th>
<td><html:text property="title" size="50"/>
<html:errors property="title"/></td>
</tr>
<tr>
<th><bean:message key="writeform.form.writer"/></th>
<td><html:text property="writer" size="10"/>
<html:errors property="writer"/></td>
</tr>
<tr>
<th><bean:message key="writeform.form.content"/></th>
<td><html:errors property="content"/>
<html:textarea property="content" cols="50" rows="10"/>
</tr>
<tr>
<td colspan="2"><html:submit titleKey="writeform.form.submit"/></td>
</tr>
</table>
</html:form>
</body>
</html:html>

액션 폼(InsertForm.java) 소스

package net.jeongsam.bboard.struts1.form;

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;

@SuppressWarnings("serial")
public class InsertForm extends ActionForm {
	private String title;
	private String writer;
	private String content;
	
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
	public String getWriter() {
		return writer;
	}
	public void setWriter(String writer) {
		this.writer = writer;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	
	@Override
	public ActionErrors validate(ActionMapping mapping,
			HttpServletRequest request) {
		ActionErrors errors = new ActionErrors();
		if (getTitle() == null || getTitle().length() == 0) {
			errors.add("title", new ActionMessage("writeform.error.title"));
		}
		if (getWriter() == null || getWriter().length() == 0) {
			errors.add("writer", new ActionMessage("writeform.error.writer"));
		}
		if (getContent() == null || getContent().length() == 0) {
			errors.add("content", new ActionMessage("writeform.error.content"));
		}
		
		return errors;
	}
}

액션(InsertAction.java) 소스

package net.jeongsam.bboard.struts1.action;

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

import net.jeongsam.bboard.model.BasicBoardDAO;
import net.jeongsam.bboard.model.BasicBoardDataBean;
import net.jeongsam.bboard.struts1.form.InsertForm;

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 InsertAction extends Action {
	@Override
	public ActionForward execute(ActionMapping mapping,
			ActionForm form,
			HttpServletRequest request,
			HttpServletResponse response)
		throws Exception {
		
		BasicBoardDataBean bbRow = new BasicBoardDataBean();
		BasicBoardDAO boardMgr = new BasicBoardDAO();
		
		bbRow.setTitle(((InsertForm)form).getTitle());
		bbRow.setWriter(((InsertForm)form).getWriter());
		bbRow.setContent(((InsertForm)form).getContent());
		
		boardMgr.insert(bbRow);
		
		return mapping.findForward("Success");
	}
}

BasicBoard_ko_KR.properties

#Generated by ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)

errors.footer = </ul>
errors.header = <ul>
errors.prefix = <li>
errors.suffix = </li>

writeform.error.content = 본문을 입력하세요.
writeform.error.title   = 제목을 입력하세요.
writeform.error.writer  = 저자를 입력하세요.
writeform.form.content  = 본문
writeform.form.title    = 제목
writeform.form.writer   = 저자
writeform.title         = 글쓰기

struts-config.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>
	<form-beans>
		<form-bean
			name="insertForm"
			type="net.jeongsam.bboard.struts1.form.InsertForm">
			<form-property name="" type=""></form-property>
		</form-bean>
	</form-beans>
	
	<action-mappings>
		<action
			name="insertForm"
			type="net.jeongsam.bboard.struts1.action.InsertAction"
			path="/insert"
			scope="request"
			validate="true"
			input="/bboard/struts1/writeForm.jsp">
			<forward name="Success" path="/bboard/struts1/result.jsp" redirect="true"/>
			<forward name="Fail" path="/bboard/struts1/writeForm.jsp"/>
		</action>
	</action-mappings>
	
	<controller
		processorClass="net.jeongsam.bboard.struts1.KoRequestProcessor"
		contentType="text/html;charset=UTF-8"
		locale="true"
		nocache="true"/>
		
    <message-resources
    	parameter="net.jeongsam.bboard.struts1.BasicBoard"
    	null="false"/>
</struts-config>

web.xml

<servlet>
		<servlet-name>Struts1Action</servlet-name>
		<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
		<init-param>
			<param-name>config</param-name>
			<param-value>/WEB-INF/struts1-config.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Struts1Action</servlet-name>
		<url-pattern>/struts1/bboard/*</url-pattern>
	</servlet-mapping>

server.xml

<Context
	docBase="MySamples"
	path="/MySamples"
	reloadable="true"
	source="org.eclipse.jst.jee.server:MySamples">
	<Resource
		auth="Container"
		driverClassName="com.mysql.jdbc.Driver"
		maxActive="100"
		maxIdle="30"
		maxWait="10000"
		name="jdbc/MySamples"
		type="javax.sql.DataSource"
		url="jdbc:mysql://127.0.0.1:3306/example?autoReconnect=true"
		username="****"
		password="****"/>
</Context>

한가지 덧붙이자면, MVC 모델에서 컨트롤러는 사용자의 요청을 받아 뷰와 모델을 선택하는 단순한 기능만을 구현하도록 하고 있다. 그래서 스트러츠1에서도 액션 폼을 컨트롤러로 보아야 하는지 모델로 보아야 하는지에 대한 논의가 상당수 있는 듯하다. 원칙론자라면 액션 폼이 컨트롤러에 종속된 면이 없지않은 이유로 모델로 볼 수 없고, 게다가 같은 이유로 모델로 볼 수도 없다는 입장이며 그런 이유로 스트러츠는 완벽하게 이론적인 MVC를 구현했다고 볼 수 없다는 의견이 있다.

+ Recent posts