SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

作りながら学ぶJavaアプリケーションフレームワーク

Struts 2入門(5)~Viewレイヤーの仕組み~

作りながら学ぶJavaアプリケーションフレームワーク (5)

  • X ポスト
  • このエントリーをはてなブックマークに追加

chainとリダイレクトとの違い

 Result Typeは大別すると、HTMLなどデータを生成するタイプと、他のActionを呼び出したりリダイレクトを行ったりする遷移タイプに分かれます。HTMLを生成するタイプは後述することにして、まずは、遷移するタイプを説明しましょう。

 Result Typeの「redirect」と「redirectAction」は、いわゆるHTTPリダイレクトを行うものです。つまり、<param>タグのlocationで指定したURIに、クライアントからあらたにリクエストが発生する形になります。

 例えば、次のように記述すると、"success"の場合、sample.jspへリダイレクトします。

<result name="success" type="redirect">
  <param name="location">sample.jsp</param>
</result>

 ここで気をつけたいのは、この処理は、デフォルトの処理であるjspファイルを利用したHTMLを生成する動作とは異なるということです。この例では、単にsample.jspへ遷移するだけであり、sample.jspでは、遷移元のリクエストで生成されたActionクラスのオブジェクトを参照することはできません。別のリクエストになっているため、元のオブジェクトは破棄され、あらたなActionクラスのオブジェクトが生成されているのです。遷移先でもデータが必要であれば、パラメータとして値を設定する必要があります。

「redirect」の処理フロー
「redirect」の処理フロー

 「redirectAction」の動作も同じで、別のActionへの遷移は、それぞれ別のリクエストにより実現されることになります。

「redirectAction」の処理フロー
「redirectAction」の処理フロー

 これらのリダイレクトを行うResult Typeと似て非なるのが、連載第3回目のサンプルに使用した「chain」というResult Typeです。「chain」は、リダイレクトではなく、同じリクエスト内の処理として別のActionを呼び出します。このとき、Actionクラスのプロパティを、遷移先のActionクラスに自動でコピーする仕組みがあり、リクエストのパラメータなどが引き継がれることになります(同じ名前のアクセッサメソッドが呼び出されます)。

「chain」の処理フロー
「chain」の処理フロー

 このような「chain」の処理は、Action間にまたがる処理のため、他のResult Typeと違って、前回説明したインターセプターとして実装されています。

 なお、実は「chain」は利用を推奨されていません。データをひきつれてActionを遷移すると、いわゆるスパゲッティコードになる恐れがあるためです。処理の流れや構造が把握しにくいアプリケーションにならないよう、「chain」の使用には十分な検討が必要です。

 Struts 2では、Actionクラスはできるだけシンプルに設計することが望ましいとされています。Actionクラスは、あくまでWebページからの窓口とし、主要な処理は別のクラスとして実装する構造(デザインパターンのFacadeパターンにあたる)が、アプリケーションの構造として推奨されています。

 このような構造では、セッション単位のデータをページ間にまたがって保持する方法が気になるところですが、このあたりはまた回をあらためて解説することにします。

データを生成するResult Type

 このタイプのResult Typeは、デフォルトの「dispatcher」をはじめとした、HTMLやバイナリデータを生成するものです。ここでは、いくつか個別にとりあげてみます。

httpheader

 「httpheader」は少し変わっていて、レスポンスにコンテンツがなく、HTMLのヘッダーだけをクライアントに返すResult Typeです。例えば、struts.xmlに次のように記述すると、ページがみつからない場合におなじみの404コードを返すことができます。

<result name="success" type="httpheader">
  <param name="status">404</param>
  <param name="headers.test1">custom header1</param>
  <param name="headers.test2">custom header2</param>
</result>

 <param>タグで、独自のヘッダー文字列を設定することもできます。このサンプルの場合、実際のレスポンスヘッダーは次のようになります。

HTTP/1.x 404 Not Found
Server: Apache-Coyote/1.1
test1: custom header1
test2: custom header2
Content-Type: text/html;charset=utf-8
Content-Length: 977
plaintext

 プレーンなテキストをクライアントに返すResult Typeです。ソースファイルの表示など、テキストをそのまま表示させたい場合に用いるもので、次のように指定します。

<result name="success" type="plaintext">
  <param name="location">/sample.txt</param>
  <param name="charSet">UTF-8</param>
</result>

 パラメータのlocationでファイルパス名、charSetで、文字コードの種別を記述します。

stream

 「stream」は、java.io.InputStreamクラスを用いたバイト列のデータをクライアントに返します。画像ファイルやPDFファイルなどを動的に生成してダウンロードする場合などに便利に使えます。例えば、次のstruts.xmlの設定例では、sample.pngという画像ファイルをダウンロードデータとして指定しています。

<action name="SampleAction" method="download" class="SampleAction">
<result name="success" type="stream">
  <param name="contentType">application/octet-streamg</param>
  <param name="contentDisposition">attachment; filename="sample.png"</param>
</result>
</action>

 <param>タグには、HTTPレスポンスヘッダに応じたパラメータを指定します。このサンプルでは、pngファイルをブラウザに表示させるのではなく、ダウンロードデータとするために、ContentTypeとContentDispositionに値を設定しています。このふたつ以外のパラータでは、特にデフォルト値を変えなくても動作します。

 なお、「stream」では、設定ファイルだけでなく、Actionクラスにも前述したInputStreamクラスを使ったコードが必要です。

 まずActionクラスには、InputStreamを返すプロパティを定義します。デフォルトでは、inputStreamという名前でゲッターを参照しますので、getInputStreamメソッドを定義し、フィールドのinputStreamを返すようにします。そして、ダウンロードの処理としては、FileInputStreamクラスを使ってファイルを読む込むようにし、inputStreamに設定します。

public class SampleAction {

    private InputStream inputStream;

    public InputStream getInputStream() {
        return inputStream;
    }

    // ダウンロードActionメソッド
    public String download() throws Exception {
        this.inputStream = new FileInputStream("sample.png");
        return "success";
    }
}

次のページ
Struts Tag

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
作りながら学ぶJavaアプリケーションフレームワーク連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3565 2009/03/04 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング