Struts 2の提供するMapへ保存し、JSPで参照する

前述の方法は、リクエストスコープの情報を扱うことは出来ますが、ページを跨るようなセッションスコープの情報を扱う事はできません。このような場合、通常であればアプリケーションサーバが提供するセッションコンテキスト(HttpSession)にオブジェクトを保持させる事になります。しかし、Struts 2では、これとは違う方法で同様の機能を提供しています。Struts 2ではアプリケーションからコンテキストへの直接アクセスは行わず、Struts 2が提供するMapによって同様の機能を実装します。このMapのオブジェクトは、アクションクラスに特定のインタフェースを実装する事で提供されるようになります。このセッションコンテキストに相当するMapにセットしたオブジェクトは、JSPからも同様のインタフェースを実装したアクションクラスからもアクセスできるようになっています。

具体的な実装は、アクションクラスにorg.apache.struts2.interceptor.SessionAwareインタフェースをimplementsし、インタフェースが要求するメソッドsetSessionを実装します。setSessionにはセッションコンテキスト相当のMapのオブジェクトが渡されますので、アクションクラスの属性としてそのオブジェクトを保持しておく必要があります。あとは、このMapオブジェクトへ保存したいオブジェクトをputするだけです。

先ほどのTop_loginアクションにユーザ情報をセッション相当のMapに追加する処理を実装する場合、下記のようになります。

リスト14: SessionAwareインタフェースをimplementsしたTop.java

package example;

import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

public class Top implements SessionAware {

    private String username;
    private String password;
    private String attention;
    private Map sessionMap;

    public void setSession(Map sessionMap) {
        this.sessionMap = sessionMap;
    }

    public String getPassword() { return password; }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getUsername() { return username; }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAttention() { return attention; }

    public void setAttention(String attention) {
        this.attention = attention;
    }

    public String execute() throws Exception {
        setAttention("Please login!");
        return "success";
    }

    public String login() throws Exception {

        if ( username == null && password == null ) {
            return "input";
        }

        if ( ! username.equals(password)) {
            sessionMap.put("USERNAME", username);
            return "success";
        }

        return "input";
    }

    public String guestLogin() throws Exception {
        return "success";
    }

}

例では、SessionAwareインタフェースによって受け取ったMapオブジェクトにログイン成功時にusernameのStringオブジェクトを、USERNAMEというキーでputしています。

このMapオブジェクトの内容をJSPからアクセスするには、<s:property>タグを用います。この時のvalue属性の記述方法はOGNL(Object-Graph Navigation Language)という式言語の一種を用いて記述します。記述の方法は、ドットでオブジェクトや属性などを繋げて表現するEL式に似ています。セッション相当のMapにUSERNAMEというキーで保存されているオブジェクトのtoStringメソッドを呼び出す場合、

<s:property value="#session.USERNAME"/>

といった記述となります。OGNLの詳細はhttp://www.ognl.org/などを参照してください。#sessionはStruts 2が提供するセッションオブジェクト相当の暗黙オブジェクトを表しています。これを、先ほど省略したHelloUserアクションのJSPであるHelloUser.jspにすると、下記のようになります。

リスト15: HelloUser.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page pageEncoding="Windows-31J" %>
<%@ taglib uri="/struts-tags" prefix="s" %>

<html>
<head>
    <title>ハロー </title>
</head>

<body>
<h2>ハロー <s:property value="#session.USERNAME"/> さん</h2>
<p>
  <a href="<s:url action="Top"/>">
      ログオフ
  </a>
</p>
</body>
</html>

このHelloUserアクションが実行されると、画面4のように表示されます。SessionAwareインタフェース以外にも、RequestAwareインタフェース、ApplicationAwareインタフェースが提供されており、それぞれリクエストコンテキスト、アプリケーションコンテキストに相当するMapが提供されるようになっていますので、必要に応じて利用してください。

画面4: ログイン成功ページ