そう。Google App Engine for JavaでHttpSessionが効かないのである。
これは相当ハマった。
深夜にしかやってないけど、数日は浪費…。
なんというか、情報が少なすぎる。
他の人はGAEでセッション情報使わないのかな…??
とか思いかけたくらい。
とまあ前置きはいいとして、本題に。
とりあえず、結論から書くと
HttpSessionが効かない。
Googleの本家の紹介ページ
や、
その他有志者等のサイトの紹介でも大体次のように書いてある。
☆以下GAEのドキュメント引用☆
セッションを有効にする
App Engine には、サーブレット セッション インターフェースによるセッションの実装が含まれています。この実装では、App Engine のデータストアと memcache を使用してセッション データを保管します。
この機能は、デフォルトでは無効になっています。有効にするには、appengine-web.xml に次の行を追加します:
<sessions-enabled>true</sessions-enabled>
この実装により、種類が _ah_SESSION のデータストア エンティティが作成され、接頭辞 _ahs のキーで memcache が作成されます。
☆引用終わり☆
Google本家はまだmemcacheという何か匂わせる記述がある。
しかし、大抵の紹介サイトはかなりの率で「セッション」という言葉以外は触れていない。
触れていても細かく実装に触れていない事が多い。
んで(二度目になるけど)結論から言うと、
Javaで馴染みがあるHttpSessionは効いてこない。
HttpSessionは定義が出来るし、使用する事もできるのだけれど
リクエストが発生する度にセッションオブジェクト内の値がnullになる
もう意味不明だった。
セッションIDは変わらないのに、オブジェクトが消えている。
しかもこれ、
ロ ー カ ル 環 境 で は 使 え て し ま う
これが諸悪の根源
ローカルで色々実装して、
さあデプロイするぞ
なんてデプロイすると、
ことごとくセッション情報が消える
結論から言うと…なんて書いといて、全然結論に至って無くて申し訳ない…w
じゃあどうすればいいか
ということになるよね。
今現在で
sessionに一番近い挙動を得ることが出ると感じたのが
「memcache」
パッケージは
com.google.appengine.api.memcache
はっきり言おう。
memcacheの仕様は、
キ ャ ッ シ ュ に 類 似 す る 機 能
って事くらいしかわかってないw
ダメじゃんて?w
だってさっき仕事から帰ってきて試してわかったばっかなんだもんorz
参考になるのは
低レベルAPIドキュメントの
ここ
memcacheの使い方は
1.まず呼び出す
MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
2.セットする(存在はMapに近い)
memcacheService.put("hoge",hoge);
3.取得する
Hoge hoge = (Hoge)memcacheService.get("hoge");
以上。
ServletとJSPでやりとりする場合は
まずServletで
MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
memcacheService.put("hoge",hoge);
をやる。(インポート忘れずに)
次にJSPで
MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
Hoge hoge = (Hoge)memcacheService.get("hoge");
をやる。
これで取得できるよ。
話は戻るけど、Google App Engineのドキュメントに合ったように、
memcacheを使う場合は
appengine-web.xml
に
<sessions-enabled>true</sessions-enabled>
を書いておかないとだめかもしれない。
そこまでは検証してないです。(soraは書いています)
気を付けることは、
putする時に、データが無いと
java.lang.IllegalArgumentException: Cannot use as value: '[]'
…
java.io.NotSerializableException: org.datanucleus.store.appengine.query.LazyResult
という警告がでます。
どういうチェックが適切かわかりませんが、気をつけて。
あと気になるのが、
未調査なんだけど
・Serializableとの関係
→memcacheはデータストアにうんたらかんたらとかセッションレプリケーションと関係する記述を見かけたので。
・タイムアウト(有効時間)
→セッションにタイムアウト時間があるので、何かしらあるはず。
かな。
すぐ思いつくのはこの程度。
データストアから取得したデータと、
生成したデータを統合して、ソートを行ってデータストアに格納しようとしたら、
エラーが…。
javax.jdo.JDOFatalUserException: Attempt was made to modify the primary key of an object of type hogehoge identified by key hogehoge(92) Primary keys are immutable.
ソートを行ったデータを、既存のデータに対して上書きをする形になったんだけど、
どうやら既存のエンティティのIDを変えようとしている処理に解釈されるようでダメみたい。
データストアのリソースを節約しようとしたのが裏目にでた模様orz
オブジェクトの削除処理が意外と面倒ではないので、
データストアを再利用しようとかいうようなヘタな更新をするよりは、
一回オブジェクトの削除 とかやって、
綺麗にした方が処理的にも楽なのかもしれない。
実際Googleから見たら大したことないんだろうけど…。
生成したデータを統合して、ソートを行ってデータストアに格納しようとしたら、
エラーが…。
javax.jdo.JDOFatalUserException: Attempt was made to modify the primary key of an object of type hogehoge identified by key hogehoge(92) Primary keys are immutable.
ソートを行ったデータを、既存のデータに対して上書きをする形になったんだけど、
どうやら既存のエンティティのIDを変えようとしている処理に解釈されるようでダメみたい。
データストアのリソースを節約しようとしたのが裏目にでた模様orz
オブジェクトの削除処理が意外と面倒ではないので、
データストアを再利用しようとかいうようなヘタな更新をするよりは、
一回オブジェクトの削除 とかやって、
綺麗にした方が処理的にも楽なのかもしれない。
実際Googleから見たら大したことないんだろうけど…。
もっと言うと
GAEでTwitter4jやって、さらにOAuthやろう
以前書いた
Twitter4j
では、認証がいらない使い方を取り上げました。
…がしかし、
Twitter4jのドキュメント
を見ながらやっていると気づくはず
何故かエラーが出る時があると
なんというか、どうしても認証をしなきゃいけない時が来るんだよね。
どういう時に認証が必要なのか…
というのは調べていないので(オイ
詳しくは書けないのですが、
全般的に、Twitterでは
アカウントを持っていないと見れない情報
と
誰でも見れる情報
があるみたいです。
この、前者のアカウントを持っていないと見れない情報について
APIを使って操作を行う時、認証が必要になる模様。
何やってた時か忘れたんだけど(オイ
例えば↓みたいなエラーが出る。(確か認証情報が中途半端な時)
java.lang.IllegalStateException: Neither user ID/password combination nor OAuth consumer key/secret combination supplied
ということでOAuth認証の準備をしちゃいましょう。
必要なのは
・Twitterへのアプリケーション登録
・appengine-web.xmlの変更
・AccessToken
・AccessSecret
です。
順番適当に書いちゃいましたが
Twitterへのアプリケーション登録をやらないと、
その下三つができないので、順序的には上からやって下さい。
次回書けたら認証方法について書いてみたいと思います。
いじょ。
GAEでTwitter4jやって、さらにOAuthやろう
以前書いた
Twitter4j
では、認証がいらない使い方を取り上げました。
…がしかし、
Twitter4jのドキュメント
を見ながらやっていると気づくはず
何故かエラーが出る時があると
なんというか、どうしても認証をしなきゃいけない時が来るんだよね。
どういう時に認証が必要なのか…
というのは調べていないので(オイ
詳しくは書けないのですが、
全般的に、Twitterでは
アカウントを持っていないと見れない情報
と
誰でも見れる情報
があるみたいです。
この、前者のアカウントを持っていないと見れない情報について
APIを使って操作を行う時、認証が必要になる模様。
何やってた時か忘れたんだけど(オイ
例えば↓みたいなエラーが出る。(確か認証情報が中途半端な時)
java.lang.IllegalStateException: Neither user ID/password combination nor OAuth consumer key/secret combination supplied
ということでOAuth認証の準備をしちゃいましょう。
必要なのは
・Twitterへのアプリケーション登録
・appengine-web.xmlの変更
・AccessToken
・AccessSecret
です。
順番適当に書いちゃいましたが
Twitterへのアプリケーション登録をやらないと、
その下三つができないので、順序的には上からやって下さい。
次回書けたら認証方法について書いてみたいと思います。
いじょ。