Struts を利用した Web アプリケーションの練習問題(解答編・その 3)

いよいよ Controller です…と言っても Struts の場合は Controller は独自に持っているので、それを補佐する Action クラスを書いてあげるだけです。

Action クラス編

ListAction.java

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.CityList;
import jp.mydns.akanekodou.dao.CityDAO;

public class ListAction extends Action {
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws Exception {
        CityList citylist = new CityDAO().all();
        request.setAttribute("citylist", citylist);
        this.saveToken(request);
        return mapping.getInputForward();
    }    
}

saveToken が初登場。token を保存することによって、正しく画面遷移が行われたかどうかを次の DetailAction.java で判断します。

DetailAction.java

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 org.apache.struts.action.DynaActionForm;

import jp.mydns.akanekodou.model.City;
import jp.mydns.akanekodou.dao.CityDAO;

public class DetailAction extends Action {
    public ActionForward execute(
        ActionMapping mapping,
        ActionForm form,
        HttpServletRequest request,
        HttpServletResponse response
    ) throws Exception {
        String forward;
        if(this.isTokenValid(request, true)) {
            DynaActionForm dform = (DynaActionForm)form;
            int id = (int)dform.get("id");
            City city = new CityDAO().find(id);
            request.setAttribute("city", city);
            forward = "detail";
        } else {
            response.setCharacterEncoding("utf-8");
            forward = "error";
        }

        return mapping.findForward(forward);
    }
}

isTokenValid で token が正しく保存されているかを確認し、正しければ(一覧画面からの遷移であれば)処理を実行して詳細画面用の JSP に forward します。そうでない場合はエラー画面に forward させます。

設定ファイル・その他編

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="detailform" type="org.apache.struts.action.DynaActionForm">
      <form-property name="id" type="java.lang.Integer" />
    </form-bean>
  </form-beans>

  <action-mappings>
    <action path="/list" type="jp.mydns.akanekodou.ListAction" input="/list.jsp" />
    <action path="/detail" name="detailform" type="jp.mydns.akanekodou.DetailAction">
      <forward name="detail" path="/detail.jsp" />
      <forward name="error" path="/error.html" />
    </action>
  </action-mappings>
</struts-config>

ActionForm クラスは独自には作らず、DynaActionForm にお任せします*1。findForward 用の設定も忘れずに。

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="struts1a" version="3.0">

  <display-name>MajorCity</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>index.jsp</welcome-file>
  </welcome-file-list>

</web-app>

filter の話は前に散々やってるので省略。

index.jsp(ダミーページ)

<!doctype html>
<html>
<head>
    <title>Index Page</title>
</head>
<body>
    <% response.sendRedirect("list.do"); %>
</body>
</html>

*1:setter と getter しかないような ActionForm を作るよりは DynaActionForm を利用した方が良いようです。