Struts1.3でGAE/Jのデータストアからファイルをダウンロードする

先のログでは、Google App Engine/Java(GAE/J)へファイルをアップロードし、データストアにBlob形式で保存をした。今回は、そこで保存したデータを取り出して、ダウンロード&復元してみる。

以下のような画面を用意し、「ダウンロード」ボタンでファイルをダウンロードする。ダウンロードするファイルは、前回のサンプルでアップロードしておく

Strutsには、v1.2から、ファイルのダウンロードのためのDownloadActionというActionクラスが用意されている。だが、ファイルシステムからのダウンロードを前提にしているので、GAE/Jでは使用することができない。したがって、(前回同様)これも昔ながらの方法でダウンロード処理を実装する。


以下の作業は、GAE/JのプラグインがインストールされたEclipse3.4(Ganymede)で行った。

プロジェクトの作成

必要なリソースはUploadのサンプルと同様のため、プロジェクトをコピーして新規web applicationプロジェクトを作成する。

エンティティーとDAO

Uploadのサンプルから流用して、RootTO、Pictureエンティティーの2つを使う。
PictureエンティティーをハンドルするDAO(PictureDao)もそのまま流用。

Actionクラスの作成

先に述べたようにStrutsで用意されているDonloadActionは使えないので、Struts1.1以前のときと同様にコーディングする。ダウンロードの対象は、numberプロパティーが1のPictureエンティティーである。このエンティティーは、前回作成したサンプルでアップロードしておく。下に示すように至って簡単なコードになる。

PictureDownloadAction.java

package test;

import java.io.IOException;

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

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.BaseAction;

import test.entities.Picture;

public class PictureDownloadAction extends BaseAction {

    @Override
    public ActionForward execute(
                ActionMapping mapping, 
                ActionForm form,
                HttpServletRequest req, 
                HttpServletResponse res) 
            throws IOException
    {
        
        PictureDao  pdao = new PictureDao();
        Picture     pic = pdao.getPictureById(1);
        String      contentType = pic.getContenttype();
        String      filename = pic.getName();
        int         filesize = pic.getSize();
        
        res.setContentType(contentType); 
        res.setContentLength(filesize); 
        res.setHeader("Content-Disposition", "attachment;filename=" + filename);
        ServletOutputStream outputStream;
        outputStream = res.getOutputStream();
        outputStream.write(pic.getPicture().getBytes());
        outputStream.flush();

        return null;
    }
}

struts-config.xml

これまで試してこなかったので、ダミーでDynaActionFormを設定してみる。

<form-beans>
    
    <form-bean
	name="pictureDownloadForm"
	type="org.apache.struts.action.DynaActionForm" >

</form-bean>

<action-mappings>

    <action path="/downloadPicture"
	type="test.PictureDownloadAction"
	name="pictureDownloadForm"
	scope="request">
    </action>

</action-mappings>

JSPの作成

先の図で示した「ダウンロードを促す画面」を作成する。

pictureDownload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>

<html:html>
<head>
    <title><bean:message key="picture.download.title" /></title>
	<link rel="shortcut icon" href="../images/egp-favicon.ico" >
</head>
<body>

<h2><bean:message key="picture.download.title" /></h2>

<html:form action="/downloadPicture" method="post">
<html:submit><bean:message key="picture.download" /></html:submit>
</html:form>

</body>
</html:html>

メッセージリソース

以下のように追加する。

MessageResources.properties

picture.download.title=GAE/J Example: Download Blob property
picture.download=download

MessageResource_ja.properties;実際には、これをnative2asciiしたものを配置する。

picture.download.title=GAE/J サンプル: Blobのダウンロード
picture.download=ダウンロード

web.xml

war/WEB-INF/web.htmlにActionサーブレットの定義と、welcome-fileを設定する。

<?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_2_5.xsd" version="2.5">

  <display-name>GAE/J Sample Application</display-name>
    
  <!-- Standard Action Servlet Configuration -->
  <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>1</load-on-startup>
  </servlet>

  <!-- Standard Action Servlet Mapping -->
  <servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  <!-- The Usual Welcome File List -->
  <welcome-file-list>
    <welcome-file>pictureDownload.jsp</welcome-file>
  </welcome-file-list>

</web-app>

appengine-web.xml

sessionをtrueに設定する。(注記;sessionを設定しないとできなかった。何故か???。間違いかな。)

	<sessions-enabled>true</sessions-enabled>

テストとデプロイ

ローカルサーバーでテストを行った後、GAE/Jにデプロイする。

「ダウンロード」ボタンを押すと、以下のようにPictureエンティティーに格納したバイナリーデータを落とすことができる。
アップロード時にContent-Typeを取得できるので、MIMEに応じてクライアントソフトを起動することもできる