dポイントプレゼントキャンペーン実施中!

お世話になります。strutsでの開発です。jdk1.5.0_09とtomcat5.5を使用しています。
下記のような流れを実現したいと思っています。参考になるサイトや文献、ヒントなどありましたらお教え下さい。
現在はリクエストフィルタを使用し、フィルタ内のメソッドdoFilter()でreq.getRequestDispatcher("/login.do").forward(req, res)を行いログイン画面まで遷移できていますが、そこでログインしてもデフォルト画面であるA画面が表示されるようになっています。
やりたい事は、セッションタイムアウト時にB画面のリクエストを受け付けると、ログイン画面へ遷移してログインリクエストで認証OKであればB画面へと遷移させたいと思っています。
不足している情報などありましたら随時追加します。よろしくお願いいたします。

ログイン画面表示
  ↓
ログインリクエスト
  ↓
A画面表示(通常ログイン時のデフォルト画面)
  ↓
[セッションタイムアウト]
  ↓
A画面でB画面をリクエスト
  ↓
ログイン画面表示
  ↓
ログインリクエスト
  ↓
B画面表示(セッション切れの状態でリクエストされた画面)

A 回答 (5件)

(1)画面Aから画面Bがリクエストされた時、セッションが切れていたら次リクエスト画面としてBを覚えてセッション変数にでも入れておく


(2)ログイン画面を表示する
(3)正常にログインできたら、セッション変数に次画面IDをチェック
 (3-1)存在したら、そのセッション変数をクリアして、そのIDをdispatch。
 (3-2)存在しなかったらデフォルト遷移先(画面A?)へdispatch

こんな単純なものじゃないです?(^-^;

この回答への補足

ご回答ありがとうございます。
まさにこの方法を昨晩気づいて色々と試行錯誤している次第です。
セッション変数というのは盲点でした、今はログイン画面にhiddenで埋め込み・・・という方法を行おうとしています。
ただ、アクションクラスでHttpServletRequestに入っている要求URI(画面B)の取り出しがうまくできずにくすぶっています。
サーブレットフィルタからforwardしているためなのか、元々GETリクエストされているからなのかが切り分け付いていませんが、POSTでないとrequestデータの中身がきちんと参照できないようです。

こちらの方と同じような状況に陥っています。
http://oshiete1.goo.ne.jp/qa2565007.html

補足日時:2007/06/05 14:25
    • good
    • 0

単純に


String url = (HttpServletRequest)request.getRequestURL();
でURLがとれなかったということですよね?

だとすると、、ごめんなさい。推測になってしまうんですが。
そもそも、A画面でセッションが切れている状態で、ログイン画面に直接dispatchして遷移したということは、
A画面とログイン画面は無関係な状態になっているってことではないですか?
「req.getRequestDispatcher("/login.do").forward(req, res)」
これだと行き過ぎで、『隣の家の中を覗こうとしている』状態になってうまくいかないんじゃないかと。

A画面から、<FORM action="~.do">
で飛んだサーブレット(画面B?)内で
if((session = (HttpServletRequest)request.getSession(false)) == null){
 // sessionがnullだったらセッションが切れているのでセッションを生成
 // A画面からのFORM情報(Bに遷移するための情報のはず)を取得して、
 // ログイン画面用の情報とB画面用の情報を生成
 // ログイン画面へ遷移(return "timeout" とかしてstruts-comfig.xmlでログイン画面へ遷移
 // <action> <forward name="timeout" path="login.jsp" /> </action>
 
ログイン処理内では、ログイン用情報以外に別画面用情報が設定されていれば、
その画面へとんでく
return("b") とかして
strtus-config.xml で
<action> <forward name="b" path="b.jsp" /> </action>

みたいな感じではないのです?(ごめん、標準的な使い方しか知らないので、、、、)

この回答への補足

たびたびのご説明大変感謝しております。
struts-configによるforwardも考えたのですが、画面が多岐に渡っていて今後も増え続ける可能性があるので一つずつの定義は不可能に近く、その方法は諦めていました。

>『隣の家の中を覗こうとしている』状態
おっしゃる通りの状況なのです。forwardされた後はA画面を表示中にB画面をリクエストしたという事実は消去されるため、HttpServletRequestの内容を引き継ぎながらリクエストされたURLを記憶するという考えに無理があったようです。

手法に誤りがあったようなので、以下の方法で組み直しています。
1.サーブレットフィルタでセッションタイムアウトと判断した場合、下記方法でlogin.doへforwardする。
  ・request.getRequestURLで取得したB画面の要求URLを取り出す。
  ・取り出したURLをlogin.doのクエリーストリングとしてパラメータにする。
   req.getRequestDispatcher("/login.do?url=" + url).forward(req, res)
2.ログイン画面表示前のActionクラス動作(defaultExcecuteメソッド)でクエリーストリングを切り出し、ログインJSPのhiddenに埋め込む。
3.ログイン実行され、ログインAction動作時にhidden値があるかどうか判断し、入っていればそのURL(B画面のURI)へforwardする。

以上の方法を試しております。もう少しスマートな方法などあるかも知れません。結果は後ほどご報告させていただきます。
重ね重ね、おつきあいいただきお礼申し上げます。

補足日時:2007/06/06 10:31
    • good
    • 0
この回答へのお礼

上記、補足の方法でうまく動作できました。
最初はセッションへ要求されたURLを格納しようともしていたのですが、そもそもセッション切れの状態でセッションのattributeが保証されず、クエリーストリング方式に切り替えてやってみたのです。
要求URLはgetRequestURLで"http://localhost:8080~/b_disp.do"のようにURIではなくURLで取得されますので、使用時に"/b_disp.do"のみを切り出してforwardするように若干手を加えています。
考え方をHttpServletRequestにこだわっていたのが間違いでした。PED02744さまの助言が心強いヒントとなりました。本当にありがとうございました。他の方にもお礼申し上げます。

お礼日時:2007/06/06 11:33

う~ん。

。。GETだと駄目ですか?
ActionServletのソースを見ている限りだと、doPostもdoGetもどっちも同じメソッドに飛んでますね。
requestから値をとるのではなく、ActionFormから値をとる必要があるような気がしますが、そうではないのです?
struts-config.xmlの<form-bean>で<form-property>の指定がないとか?

あ、strutsのバージョンが書かれていなかったので、手元の資料(多分1.3(古!))を元に回答しています(^-^;

この回答への補足

PED02744さま、おつきあいいただきありがとうございます。
ActionFormですか、、、視点が違っていますでしょうか(汗)
strutsは1.3.5を使用しております。

LoginActionで下記のような事をやっています。spring-fwと組み合わせていますので戻り値はStringになっていますが、基本はstrutsと同じかと思います。

protected String defaultExecute(ActionMapping mapping, ActionForm form,
HttpServletRequest req, HttpServletResponse res) throws Exception {
// リクエストされたuriをフォームへ格納し、jspのhiddenに設定する(ただし、ログインuri以外のリクエスト時のみ)
LoginForm fm = (LoginForm) form;
if (req.getHeader("Referer") != null && req.getHeader("Referer").lastIndexOf("/login.do") == -1) {
fm.setReqUri(req.getHeader("Referer"));
}

return "default";
}

defaultExcecuteメソッドはログイン画面が要求された時に自動的に呼び出されるメソッドです。ここで本来ならばリクエストされたURIを取得したいところです。(今は試しにRefererを取っていますがこれは間違いです)

この中でActionFormの内容を見てみましたがURL,URIらしきものは見あたりませんでした。逆にHttpServletRequestの中にはログイン画面のURI(/login.do)とは別に、リダイレクトされる前のURI(/hogehoge.do)がrequest~coyoteRequestに見えています。この/hogehoge.doを取り出したいのです。
ここまでは確認できているのですが、それを取り出す術が見つからないのです・・・
req.getInputStream()で取得を試みましたが先ほどご紹介のQ&Aと同様にreadLine()の結果は-1となっております。サーブレットフィルタからはreq.getRequestDispatcher("/login.do").forward(req, res)と処理していますので"GET"の動作かと思われ、POSTでないと取得できないのか??までは考えが及んでいます。

補足日時:2007/06/05 18:33
    • good
    • 0

自分だったら、ログイン画面で、ログイン成功後の画面のキー(URL、アクション名、etc.)をパラメータから貰うと思います。


あとは、全体の実装との絡みによってですが、
1)ログイン処理しているサーブレット/アクションで RequestDispatcher で forwardする。
2)ログイン処理後、forwardするJSPは同じ。JSPから再度、行きたい画面/アクションへforward。
3)sendRedirectする(パラメータが必要な場合、&GET送信がOKな場合)。
4)ログイン処理後、forwardするJSPは同じ。JSPはレスポンスする。JSPは、<form>をログイン後に進むためのリクエスト先/パラメータを設定して、<html>タグのonload属性を利用して、JavaScriptでフォームを送信する(パラメータが必要な場合、&POST送信が必要な場合)。

この回答への補足

ご回答ありがとうございます。
一旦、jspをクライアントへレスポンスして、javascriptで次のurlをリクエストさせて遷移させるという方法ですね。
この方法ですと一度ログイン後のデフォルト画面がブラウザに表示され、直後遷移して・・・という動きとなりそうなのです。

要求の動きとしては、ログイン認証処理をサーバーで行い、認証OKとなれば元々リクエストされたurl(uri)の機能画面をレスポンスしたいのです。
数分~数十分放置され、セッションタイムアウトした状態というのはどこの画面でも起こりうる事なのですが、その状態で次のアクションがリクエストされたらログイン動作(当然ログイン操作が必要ですが)を必ず経由して、リクエストされた画面をクライアントへ直接返却する動きを模索しています。
たまにどこかのサイトなどで見かけますのでありがちな処理だとは思いますが、今回この手のリダイレクトやらは初めて実装するのでちょっと手こずっています。

補足日時:2007/06/04 17:40
    • good
    • 0

ログインしたらA画面が表示されていいのではないですか?


何で困っているのか分かりません。
具体的に、何をどうしたいか述べて下さい。

あと、これは実装の具体的な方法なので、参考になる文献やサイトは少ないような気がします。
基本的な技術は備えてるようなので、あとは具体的にどういうつくりにするかを紙に書くなりして設計してみては?

この回答への補足

すみません、説明不足ですね。
ログインしてA画面(/a_disp.do)が表示されるのは通常のログイン画面表示が要求(/login.do)され、そこでログイン成功した場合に自動表示されるのはこれはこれで設計上の動きは正解です。

一方、ログインして自動的にA画面を表示したままセッションが切れ、それに気づかずにB画面遷移ボタン(リンクなど)を押下するとセッション切れと判断し、再度ログインさせるため一旦はログイン画面を表示、ログインに成功するとA画面(/a_disp.do)を経由せずにユーザが要求していたB画面(/b_disp.do)を直接表示させてあげたいのです。

>参考になる文献やサイトは少ないような気がします。

ですねぇ。。。どこもセッションタイムアウトの時は単純にログイン画面へ遷移するようなサンプルでして、ログイン完了とともに要求時のURL(/b_disp.do)へ遷移するパターンがなかなか見つからないのです。

ログイン用のアクションクラスでdefaultExcecute()が呼び出された時点でHttpServletRequestの中を覗いてみますとcoyoteRequestに"/b_disp.do"というような情報は入っているのですが、これをどのようにして活用(引き継ぎ)すべきかが今ひとつ見えていません。的外れかも知れませんがHttpServletRequestとHttpServletResponseの関係を再確認した方がよさそうです。

補足日時:2007/06/04 15:19
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!