ウェルカムページindex.jspを<iframe></iframe>
で使用するアプリケーションがあります。iframeのコンテンツはjsfページです。 index.jspにアクセスすると、firebugの最初の取得時にすでにCookieが表示されます。
Set-Cookie JSESSIONID=C615DA89B6EF73F801973EA3DCD3B226; Path=/
<iframe>
のページはこのjsessionidを継承します。しかし、<iframe/>
のページに直接アクセスすると、最初のリクエストでjsessionIdがCookieなしですべてのURLに書き換えられます。その後、Cookieが使用されます。これはすべて問題ありません-次の場合:セキュリティシステムにより、URLの書き換えを実行できます。
Jboss4.2.2を実行します
Index.jspの場合と同じ動作を実現したい-例:常にCookieを使用し、常にhttpの書き換えを避けてください。
[編集] 私がこれを書いたbaluscの答えのおかげで:
public class JsessionIdAvoiderFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
ServletException {
boolean allowFilterChain = redirectToAvoidJsessionId((HttpServletRequest) req, (HttpServletResponse)res);
//I'm doing this because if I execute the request completely, it will perform a pretty heavy lookup operation. No need to do it twice.
if(allowFilterChain)
chain.doFilter(req, res);
}
public static boolean redirectToAvoidJsessionId(HttpServletRequest req, HttpServletResponse res) {
HttpSession s = req.getSession();
if(s.isNew()) {
//after the redirect we don't want to redirect again.
if(!(req.isRequestedSessionIdFromCookie()&&req.isRequestedSessionIdFromURL()))
{
//yeah we have request parameters actually on that request.
String qs = req.getQueryString();
String requestURI = req.getRequestURI();
try {
res.sendRedirect(requestURI+"?"+qs);
return false;
} catch (IOException e) {
logger.error("Error sending redirect. " + e.getMessage());
}
}
}
return true;
}
}
web.xml
に追加することを忘れないでください
<filter>
<display-name>JsessionId Filter</display-name>
<filter-name>jsessionIdAvoiderFilter</filter-name>
<filter-class>my.namespace.JsessionIdAvoiderFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>jsessionIdAvoiderFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
サーブレット3.0以降、これには_<tracking-mode>COOKIE</tracking-mode>
_を使用できます。ただし、JBoss4.2.2はサーブレット3.0に準拠していないため、これはオプションではありません。
最も簡単なのは、 HttpServletRequest#getRequestURI()
がtrue
を返すときに HttpSession#isNew()
にリダイレクトを送信するサーブレットフィルターを作成することです。クライアントがCookieをまったくサポートしていない場合に、無限のリダイレクトループを防ぐために、 HttpServletRequest#isRequestedSessionIdFromCookie()
を確認することを忘れないでください。
クリストファーシュルツの推奨に基づいて、私はこれを試しましたが、うまくいきました。
package com.rama.test.jsessionfilter
public class JsessionIdAvoiderFilter implements Filter {
protected static final Logger LOGGER = LogManager.getLogger(JsessionIdAvoiderFilter.class);
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
if (!(req instanceof HttpServletRequest)) {
chain.doFilter(req, res);
return;
}
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// Redirect requests with JSESSIONID in URL to clean old links
/* If you really want clean up some old links which have Jsession id bookmarked clean it. If its new app
this below check is not required. */
if (request.isRequestedSessionIdFromURL()) {
String url = request.getRequestURL().append(request.getQueryString() != null ? "?"
+ request.getQueryString() : "").toString();
response.setHeader("Location", url);
response.sendError(HttpServletResponse.SC_MOVED_PERMANENTLY);
LOGGER.info(" Found url with jsession id in it:"+ request.getRequestURL() +": url="+url);
return;
}
// Prevent rendering of JSESSIONID in URLs for all outgoing links
HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper(
response) {
@Override
public String encodeRedirectUrl(String url) {
return url;
}
@Override
public String encodeRedirectURL(String url) {
return url;
}
@Override
public String encodeUrl(String url) {
return url;
}
@Override
public String encodeURL(String url) {
return url;
}
};
chain.doFilter(req, wrappedResponse);
}
public void destroy() {
}
public void init(FilterConfig arg0) throws ServletException {
}
}
およびweb.xmlの次のエントリ
<filter>
<display-name>JsessionId Filter</display-name>
<filter-name>jsessionIdAvoiderFilter</filter-name>
<filter-class>com.rama.test.jsessionfilter.JsessionIdAvoiderFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>jsessionIdAvoiderFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
よく働く !!!。
これは、HttpServletRequest.encodeURLおよびHttpServletRequest.encodeRedirectURLをオーバーライドするHttpServletRequestでリクエストをラップする単純なフィルターを使用して実行できます。渡されたString引数を返すだけで、URLの書き換えが無効になります。これは、conf/web.xml
(非推奨)で構成するか、すべての個別のWebアプリで構成する場合を除いて、単一のWebアプリでのみ機能することに注意してください。
この手法は、リクエストの速度を低下させる可能性のあるリダイレクトを必要としないため、質問の後半に投稿された手法よりも優れています。 IMO、それもきれいです。