Struts2をやってみる (10) - HTTP Session -

2013-09-22T00:00:00+00:00 Java Struts2

Struts2でセッション管理な機能を使うには

  • org.apache.struts2.interceptor.SessionAwareを実装する
  • setSession(Map)なメソッドが発生する

っていう感じらしい。でセッションにデータを突っ込むにはsetSessionの引数で指定されるMap<String, Object>にデータを突っ込んでいく模様

package sample.action;

import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;

public class IndexAction extends ActionSupport implements Preparable, SessionAware {

    private static final long serialVersionUID = 1L;
    private Map<string, Object> userSession;

    @Override
    public void setSession(Map<string, Object> session) {
        userSession = session;
    }

    @Override
    public void prepare() throws Exception {}

    public void prepareInput() {
        userSession.put("message", "hoge fuga foobar");
    }
}

っていう場合、流れは

  • setSession
  • prepareInput
  • input

という流れで実行される模様。でstruts.xmlで定義する際には

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <constant name="struts.devMode" value="true" />

    <package name="sample" extends="struts-default" namespace="/sample">
        <action name="index" class="sample.action.IndexAction" method="input">
            <interceptor-ref name="defaultStack">
                <!-- sessionパラメーターを指定しても除外されるように -->
                <param name="params.excludeParams">^session</param>
            </interceptor-ref>
            <result name="input">/WEB-INF/jsp/index.jsp</result>
        </action>
    </package>
</struts>

上記に書いてあるexcludeParamsを設定せずに、/index.action?session=hoge とかでアクセスしてしまうとsetSession(String)が発生。でもそんなメソッド無いって事でNoSuchMethodExceptionが出る。そういう事象を発生させないようにparams.excludeParamsは適切に設定する必要性があるかと。ちなみに公式ドキュメントなサンプルとかだとインターセプタースタックを作ってそこをデフォルトとして利用している模様

でJSPとかでは

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="utf-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
  <head>
    <meta charset="utf-8" />
    <s:head />
  </head>
  <body>
    ${session.message}
  </body>
</html>

というような感じで${session}で評価して取得できるのでそれを利用する。

余談: セッション管理が関係する場合のテスト

ActionProxyを通じてexecuteした場合においても、setSessionまでは処理が行われない模様。なので自前でそういう処理をしてからexecuteすれば良いっぽい

package sample.action;

import java.util.HashMap;
import java.util.Map;

import org.apache.struts2.StrutsTestCase;
import org.junit.Test;

import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.ActionSupport;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

public class IndexActionTestCase extends StrutsTestCase {

    private static Map<string, Object> session = new HashMap<string, Object>();

    @Override
    protected ActionProxy getActionProxy(String uri) {
        ActionProxy proxy = super.getActionProxy(uri);
        proxy.getInvocation().getInvocationContext().setSession(session);

        return proxy;
    }

    @Test
    public void test_index() throws Exception {
        assertThat(session.size(), is(0));

        ActionProxy proxy = getActionProxy("/sample/index.action");
        assertThat(proxy.execute(), is(ActionSupport.INPUT));

        assertThat(session.size(), is(1));
    }
}

staticにするか否かは要件次第なんじゃないのかと。

以上。微妙にグダグダな感じになったので色々やってみて追記するかも知れないので(ry

Struts2をやってみる (9) - Preparable Interface -