いくつかの奇妙なバグがあります。ブラウザで初めてページを開いたとき、すべての参照にjsessionidパラメータ(<a href="/articles?name=art&jsessionid=5as45df4as5df"..>
など)があります。
F5キーを押すか、他の方法でページを更新すると、すべてのものが消え、ブラウザーを閉じるまですべてが正常に機能します(すべてのタブも閉じる必要があります)。もう一度開くと、この奇妙なjsessionidパラメータが表示されます。
すべてのURLを作成するためにjstl <c:url..>
タグを使用します。
Cookieが無効になっている場合、jsessionidはCookieの代わりになることを少し前に読んだことがありますが、Cookieは有効になっていて、実際にはCookieを使用していません。
これはバグではなく、仕様によるものです。新しいセッションが作成されると、サーバーはクライアントがCookieをサポートしているかどうかを確認できないため、URLにjsessionidだけでなくCookieも生成します。クライアントが2回目に戻ってCookieを提示すると、サーバーはjsessionidが不要であることを認識し、残りのセッションでそれをドロップします。クライアントがCookieなしで戻ってきた場合、サーバーはjsessionidの書き換えを引き続き使用する必要があります。
明示的にCookieを使用することはできませんが、暗黙的にセッションがあり、コンテナはそのセッションを追跡する必要があります。
skaffman's answer で説明されているように、はバグではありません。その予想される動作。
あなたの質問では、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
_。
このソリューションはコンテナに依存しません(Tomcatのようなサーブレット仕様v3準拠のコンテナはソリューションではありません)。応答URLのフィルタリングはハックのように感じられるため、デフォルトの動作を変更する必要があります。しかし、すべてはあなたが必要とし、達成したいことに依存しています。
Tomcat 7または任意のサーブレット仕様v3準拠サーバーでは、アプリケーションのweb.xmlに以下を追加することにより、URLのjsessionidを無効にすることができます
<session-config>
<tracking-mode>COOKIE</tracking-mode>
</session-config>
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パターンにマッピングします。
すべてのページが使用する共通のラッパーページがある場合(私にとってはcommon.incでした)、session="false"
を<%@ page
に追加して、セッションIDを削除できます。
例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構成に追加して、セッションIDを切り捨てることもできます。
ReWriteRule ^/(\w+);jsessionid=\w+$ /$1 [L,R=301]
ReWriteRule ^/(\w+\.go);jsessionid=\w+$ /$1 [L,R=301]
残念ながら、これを回避する唯一の方法は、jsessionidパラメータを取り除くフィルタをアプリケーションに追加することです。公開Webサイトを作成していて、検索エンジンでページのインデックスを作成したい場合は、特に煩わしいです。
Tomcat(もしそれがあなたが使っているものなら)がこれをあなたのURLに追加しないように設定できるとは信じていません。他のサーバーについては言えません。
ただし、フィルターを作成してからセッション管理が必要で、ユーザーがCookieをオフにしている場合は、問題が発生することに注意してください。
回避策の1つは、<c:url>
を使用するのではなく、${request.contextPath}/path
を使用することです。