SAStruts + JQueryでのAjaxリクエスト判定の方法
はーい、元気ですかー?ロックンロール!
今現在、SAStrutsを使い始めて2つめのプロジェクトを荒々しくコーディング中なんですが、今回はJQueryを利用したAjax処理をあちこちで採用してます。
マスタ管理とかの一覧のページングとかはAjaxだし、追加・更新もajaxでlightbox風な感じで表示してるし。
で、リクエストが正常に処理された場合はおkなんですが、入力エラーだったりセッションが切れてたり例外が出たときに、デフォルトのままエラー画面とかにforwardすると、ブラウザ側でエライことになっちまいますよね?
divの中にエラー画面がloadされたり、javascriptをevalしようとしたら実はHTMLだったぜ的な。
そこで、今回はRequestのヘッダーの中身によって、Ajaxでのリクエストなのか、クライアントはHTMLを期待しているのかそれともjavascriptやjsonを期待しているのかを判定して、forward先を変更する処理を実装しました。
例外処理の場合は、ExceptionHandlerの中で、こんな感じでAjaxか判定してますよ。
@Override public ActionForward execute(Exception ex, ExceptionConfig ae, ActionMapping mapping, ActionForm formInstance, HttpServletRequest request, HttpServletResponse response) throws ServletException { if( isAjax( request ){ if(isRequiredJs( request ) ){ return new ActionForward( "/WEB-INF/view/ajaxErrorJs.jsp" , false); } return new ActionForward( "/WEB-INF/view/ajaxError.jsp" , false); } return super.execute(ex, ae, mapping, formInstance, request, response) } static boolean isAjax( HttpServletRequest request ){ return StringUtil.equals("XMLHttpRequest", request.getHeader("X-Requested-With")); } static boolean isRequiredJs(HttpServletRequest request ){ return ( StringUtil.contains(accept, "text/javascript") || StringUtil.contains(accept, "application/javascript") ); }
えー、boolean isAjax( HttpServletRequest request )で、JQueryから$.ajax()や$(selector).load()などでリクエストすると、HTTPHeaderにX-Requested-With:XMLHttpRequestと設定されるのを利用して、ajaxのリクエストであるか判定してます。
ただ、このままでは、ブラウザがHTMLが欲しいのかjavascriptが欲しいのか分かりません。
HTMLが欲しい場合はエラーメッセージをdivの中に表示したいし、javascriptの場合はエラーメッセージをalertするなりdivにつっこむなりのスクリプトを返すようにしたいわけです。
そこで、boolean isRequiredJs(HttpServletRequest request )でHTTPHeaderのAcceptを見て、"text/javascript"や"application/javascript"が含まれていればjavascriptを要求しているものとして判定しています。
同様の対応で、セッションが切れいている場合や入力エラーの場合にも、forward先のjspを切り替えることで対応できると思います。
ただし、HTMLを要求する場合は$(selector).load()を利用し、javascriptを要求する場合は$.ajax()でdataType:'script'を指定してリクエストを送るということが前提条件となります。