5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[SpringBoot,Thymeleaf] ページの一部だけ更新する際のセッションタイムアウト対応

Posted at

SpringBoot+ThymeleafでAjax処理してHTMLを部分的に書き換える場合があります。
検索処理をAjaxでやって検索結果のところだけ動的に書き換える、みたいな感じですね。
別にSpringBoot+Thymeleafじゃなくたってありますが。
SpringBootと言ってますが要はSpringMvcですね。

この組み合わせでやるとき、Controllerの戻り値を

Return "hogehoge:fugafuga"

のようにしてth:fragmentを指定した一部分のHTMLだけを返すようにします。

WS000039.JPG
こんな感じですね。
「検索」、「クリア」のあと、「前へ」の手前までの部分がfragmentになっています。

が、こうしているとセッションタイムアウトしている場合に悲劇が発生します。

具体的には
WS000040.JPG

こうなります。
fragmentの部分にログイン画面がはまってしまいました。

SpringSecurityの認証フィルタを使うとタイムアウトしている場合は自動的にログイン画面に飛ばしてくれるのですが、ajaxでfragment部分だけ戻している場合も例外では無く。

さてさて、これでは大変見栄えがよろしくないのでなんとかしたいところです。
しかしサーバーサイドではSpringSecurityがばっちり拾ってくれているので介入のしようが無く、クライアントサイドでは正常(ステータスコード=200)でログイン画面が返ってきます。
さてどうしたものか。

返ってきたのがログイン画面だったらリダイレクトすればいいじゃない。

というわけでログイン画面にコメントで目印を埋め込んで・・・

ログイン画面先頭
<!DOCTYPE html> <!-- this is login form -->
<html xmlns:th="http://www.thymeleaf.org">

それを見つけたらリダイレクト!

js-Ajax共通処理
// タイムアウトしてから検索すると、検索エリアにログイン画面が埋め込まれる事象の対応
$(document).ajaxSuccess(function(e, xhr, options){
    // レスポンスにDOCTYPEが含まれたらログイン画面と判断する
    if(xhr.responseText.match(/<!-- this is login form -->/)){
    	// ログイン画面を受信した場合は自画面に遷移させる(ことで親画面をログイン画面にする)
    	window.location.href = './';
    	return false;
    }
});

fragmentでは含まない<!DOCTYPE html>を拾おうかとも考えたのですが、一応ログイン画面に限定した実装にしておこうかと。

力技ですのでもっとスマートなやり方をご存じの方は是非コメントをお願いします。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?