JSESSIONIDは、JSTL タグによって生成されるすべてのURLで発生します。
-
20-08-2019 - |
質問
いくつかの奇妙なバグがあります:いくつかのブラウザで初めてページを開くと、すべての参照はjSessionIDパラメーターを持っています( <a href="/articles?name=art&jsessionid=5as45df4as5df"..>
).
F5を押すと、他の方法でページを更新すると、ブラウザを閉じるまですべてが消え、すべてが正常に機能します(すべてのタブも閉じる必要があります)。もう一度開くと、この奇妙なjSessionIDパラメーターが表示されます。
JSTLを使用します <c:url..>
すべてのURLを作成するためのタグ。
Cookieが無効になっている場合、JSessionIDはCookieの代替品であるが、Cookieが有効であり、実際にはCookieを使用していないことを少し前に読んだことがあります。
解決
これはバグではなく、設計によるものです。新しいセッションが作成されたとき、サーバーはクライアントがCookieをサポートするかどうかはわかりません。したがって、URL上のJSessionIDと同様にCookieを生成します。クライアントが2度目に戻ってきて、Cookieを提示すると、サーバーはJSessionIDが必要ではないことを知っており、セッションの残りのためにドロップします。クライアントがCookieなしで戻ってきた場合、サーバーはjSessionIDの書き換えを引き続き使用する必要があります。
Cookieを明示的に使用することはできませんが、暗黙的にセッションを行い、コンテナはそのセッションを追跡する必要があります。
他のヒント
説明したように スカフマンの答え, それはバグではありません。その予想される動作.
あなたの質問では、JSessionIDはパラメーターとして追加されていますが、そうではありません。
使用
<c:url value="/"/>
次のようなものを生成します: /some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FA
.
だから使用してください
<link href="<c:url value="/"/>stylesheets/style.css" rel="stylesheet" type="text/css"/>
生成します
/some/;jsessionid=E85FAC04E331FFCA55549B10B7C7A4FAstylesheets/style.css
、そのため、サーバーは利用可能なリソースを見つけることができません。
私が見つけた最高の回避策はそうです 使用する ${pageContext.request.contextPath}
それ以外の <c:url value="/"/>
. 。したがって、前の例では、あなたが持っているでしょう
<link href="${pageContext.request.contextPath}/stylesheets/style.css" rel="stylesheet" type="text/css"/>
それは生成されます
/some/stylesheets/style.css
.
このソリューションはです コンテナが独立しています (一方、サーブレット仕様V3準拠のコンテナ - Tomcatのような - ソリューションはそうではありません)。応答URLのフィルタリングは、ハックのように感じられます。これは、デフォルトの動作を変更する必要があるためです。しかし、すべてがあなたが必要とし、達成したいことに依存します。
Tomcat 7または任意のサーブレット仕様V3コンプライアントサーバーで、アプリケーションのWeb.xmlにFollowを追加することにより、URLでJSessionIDを無効にできます
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
これがaの風味の厄介な回避策です Filter
そのため、クライアントがCookieをサポートするたびに、URLでJSessionIDを表示することはありません。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
if (session.isNew()) {
// New session? OK, redirect to encoded URL with jsessionid in it (and implicitly also set cookie).
res.sendRedirect(res.encodeRedirectURL(req.getRequestURI()));
return;
} else if (session.getAttribute("verified") == null) {
// Session has not been verified yet? OK, mark it verified so that we don't need to repeat this.
session.setAttribute("verified", true);
if (req.isRequestedSessionIdFromCookie()) {
// Supports cookies? OK, redirect to unencoded URL to get rid of jsessionid in URL.
res.sendRedirect(req.getRequestURI().split(";")[0]);
return;
}
}
chain.doFilter(request, response);
}
マップします /*
または、セッション管理を必要とするURLパターン。
すべてのページが使用する一般的なラッパーページがある場合(私にとっては一般的でした。inc)追加できます session="false"
あなたに <%@ page
SessionIdを削除します。
例 common.inc
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false" trimDirectiveWhitespaces="true" %>
<%@ taglib prefix="ab" tagdir="/WEB-INF/tags" %>
<c:set var="contextPath" scope="request" value="${ pageContext.request.contextPath }" />
<c:set var="assetPath" scope="request" value="/assets" />
<c:set var="debugEnabled" scope="request" value="${ applicationDebugProperties.debugEnabled }" />
または、の値を設定します c:url
変数に使用して使用します c:out escapeXml="false"
変数を出力すると、セッションIDが削除されます。
例:
<c:url value=${url} var="image"/>
<c:out var=${image} escapeXml="false"/>
または、これをApache構成に追加してSessionIDを切り捨てることもできます。
ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]
残念ながら、私がこれについて見つけた唯一の方法は、jSessionIDパラメーターを剥奪するアプリケーションにフィルターを追加することです。パブリックウェブサイトを作成していて、検索エンジンにページのインデックスを作成したい場合は、特に迷惑です。
Tomcat(それがあなたが使用しているものであれば)をあなたのURLに追加しないように構成できるとは思いません。しかし、他のサーバーについては言えません。
ただし、フィルターを作成し、セッション管理が必要であり、ユーザーがCookieをオフにしている場合、問題に遭遇することに注意してください。
1つの回避策は使用しないことです <c:url>
, 、しかし使用する ${request.contextPath}/path