GAEのコーディング覚え書き

さっそくブログ放置し過ぎてました。。

今日は忘れないうちにslim3 on GAEでコーディングをしてて、個人的にハマったところなどを覚え書きー。
今回は初歩的なことかもですが、セッションでDTOを扱う際の注意点です。(slim3で書いてますがこれはGAEの仕様です)

セッションからDTOを取り出して中身を変更したら、もう一度セッションにDTOをセットし直さないと反映されない!


これは本番環境とローカル環境で挙動が違うのでハマった事象でした。  
例えば、

DTO

public class HogeDto implements Serializable {
    
    private String value;
    
    // 〜〜 アクセッサ省略

}

このDTOvalue値の変化を見るために、次の3ページの遷移をさせます。

  • 初期ページ … HogeDtoの生成とvalueに初期値をセットして、セッションにセット
  • 2ページ目 … セッションからHogeDtoを取り出してvalueの値を上書き
  • 3ページ目 … セッションからHogeDtoを取り出してvalueの値を出力

・初期ページのController

public class FirstController extends Controller {
    public Navigation run() {
        
        HogeDto dto = new HogeDto();
        dto.setValue("初期値です");
        sessionScope("dto", dto);
        
        return forward("first.jsp");
    }
}

・2ページ目のController

public class SecondController extends Controller {
    public Navigation run() {
        
        HogeDto dto = sessionScope("dto");
        dto.setValue("2ページ目でセットした値です");
        
        return forward("second.jsp");
    }
}

・3ページ目のController

public class ThirdController extends Controller {
    private static Logger log = Logger.getLogger(ThirdController.class);
    public Navigation run() {
        
        HogeDto dto = sessionScope("dto");
        log.info("HogeDtoのvalue値は … "+ dto.getValue());
        
        return forward("third.jsp");
    }
}

JSPは省略しますが、first→second→thirdの順に遷移すると・・


■開発環境の結果

「HogeDtoのvalue値は … 2ページ目でセットした値です」

■本番環境の結果

「HogeDtoのvalue値は … 初期値です」

となります。


本番環境では、DTOをセッションにセットした時にシリアライズされるようですね。
*厳密にはセットしたタイミングで”予約”のような動きをしてて、実際にシリアライズされるのはそのサーブレット処理が終わった後のようです。詳細後述。


結構作り込んだ後でこの問題に気づき、セッションでDTOを持ち回してる全ての箇所に”セット処理”を書くのは面倒だったので、

セッションから値を取り出したらすぐにセットし直す

という対応を親クラスに入れ込みました。

slim3なのでこんな感じ

public abstract class AbstractBaseController extends Controller {
    /**
     * GAE本番環境のSessionスコープオブジェクトは処理内でsetAttributeしておかないと
     * 変更が反映されない為、取得時にすぐセットしておく。
     */
    @Override
    protected <T>T sessionScope(CharSequence name) {
        T t = super.sessionScope(name);
        super.sessionScope(name, t);
        return t;
    }
}

このクラスを先程のfirst〜thirdのControllerに継承させることで、本番環境でも開発環境と同じ動作をするようになりました!


前述で”予約”のような動き、と言ったのは、このようにゲット→セットを一連でやっておけば、その後のDTOの値の変更がちゃんと反映される為です。
以上、セッションDTOの覚え書き。

チラ裏

はてなのブログ編集に慣れず、時間掛かるー・・・orz