フレームワークを使って Web アプリケーションを再構築しよう(その 1)

前回 ServletJSP で Web アプリケーションを作りましたが、今回はそれを Struts を利用して書き変える作業をします。

Model の修正

Customer.java を以下のように修正します。

package jp.mydns.akanekodou.model;

public class Customer {
    private String id;
    private String name;
    private String phone;

    public Customer() { }

    public String getId() {
        return id;
    }

    public void setId(int id) {
        this.id = Integer.toString(id);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

変更点は id が int 型から String 型になったことと、それに伴う getId の返り値の変更、setId の変更です。int 型のままだと View の書き変えの際に使う bean:write 要素で扱うことができないのでこのようにします。また、View で扱いやすくするために補助的な CustomerList.java を作成します。

package jp.mydns.akanekodou.model;

import java.util.List;
import java.util.ArrayList;

public class CustomerList {
    private List<Customer> list;

    public CustomerList() {
        list = new ArrayList<Customer>();
    }

    public List<Customer> getList() {
        return list;
    }

    public void setList(List<Customer> list) {
        this.list = list;
    }

    public void add(Customer c) {
        list.add(c);
    }
}

View の修正

<%@ page language="java" contentType="text/html; charset=utf-8" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>
<!doctype html>
<html:html>
<head>
  <title>顧客マスタ一覧</title>
</head>
<body>
  <bean:define id="list" name="list" scope="request" type="jp.mydns.akanekodou.model.CustomerList" />
  <h1>顧客マスタ一覧</h1>
  <table border>
    <thead>
      <tr><th>ID</th><th>顧客名</th><th>連絡先</th></tr>
    </thead>
    <tbody>
    <logic:iterate id="cust" name="list" property="list" scope="request">
    <tr>
      <td><bean:write name="cust" property="id" /></td>
      <td><bean:write name="cust" property="name" /></td>
      <td><bean:write name="cust" property="phone" /></td>
    </tr>
    </logic:iterate>
    </tbody>
  </table>
</body>
</html:html>

かなり大幅な書き変えになりますが、Java のコード(for 文など)が消えましたね。これでもまだプログラミング(というか Struts)の知識を必要としますが、幾分か HTML に近づいた形になります。

Controller の修正

何はともかく Struts のライブラリ群を用意しなければいけないので、Struts のライブラリ群を WebContent/WEB-INF/lib 以下に配置します。全部入れてもいいのですが、以下の 10 個があれば最低限の機能は用意できます。

  • antlr-2.7.2.jar
  • commons-beanutils-1.8.0.jar
  • commons-chain-1.2.jar
  • commons-digester-1.8.jar
  • commons-logging-1.0.4.jar
  • commons-validator-1.3.1.jar
  • oro-2.0.8.jar
  • struts-core.1.3.10.jar
  • struts-taglib-1.3.10.jar
  • struts-tiles-1.3.10.jar

そして web.xml を書き変えます。

<?xml version="1.0" encoding="utf-8"?>
<web-app
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
  id="WebApp_ID" version="3.0">

  <display-name>Customers</display-name>

  <servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>/WEB-INF/struts-config.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  <filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>jp.mydns.akanekodou.filter.EncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>language</param-name>
      <param-value>ja</param-value>
    </init-param>
  </filter>

  <filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <welcome-file-list>
    <welcome-file>init.do</welcome-file>
  </welcome-file-list>

</web-app>

servlet 要素と servlet-mapping 要素が大幅に書き換わっています。全然簡単になってないじゃないか、と思われそうですが、こう書いておけば、後々機能を追加してもいちいち web.xml を編集する必要がなくなります。

続いて、WebContent/WEB-INF 以下に 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>

  <action-mappings>
    <action path="/init" type="jp.mydns.akanekodou.InitAction" input="/init.jsp" />
  </action-mappings>

</struts-config>

最後に action-mappings で指定した InitAction クラスを作成します。前回作った InitServlet はもう必要ありません。

package jp.mydns.akanekodou;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import jp.mydns.akanekodou.model.CustomerList;
import jp.mydns.akanekodou.dao.CustomerDAO;

public class InitAction extends Action {
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws Exception {
        CustomerList list = new CustomerDAO().all();
        request.setAttribute("list", list);
        return mapping.getInputForward();
    }
}

いろいろとクラスを import してますが、処理そのものはすっきりしました。

  1. データベースから顧客の一覧を取得する
  2. request にその値をセットする
  3. forward する(forward 先は struts-config.xml で指定した JSP ファイル)

これで前回と同じ画面が出てくれば、書き換えが正しく行われたことになります。

データベースへの接続方法に関しては今回はそのまま引き継ぎましたが、他にもデータベースへの接続方法があるので、次回はそれを紹介したいと思います。