初回アクセス時はセッション維持にcookieが使えるか判断できず、埋め込むURLにセッションIDを入れる動きをします。
フレームワークやJSTLで使用されるencodeURLの結果にjsessionidが含まれるので
その結果からjsessionidを無理やり消す形で対応。
CutJsessionidFilter.java
package ex.web.interceptor;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class CutJsessionidFilter implements Filter {
private static class CutJsessionidResponseWrapper extends
HttpServletResponseWrapper {
public CutJsessionidResponseWrapper(final HttpServletResponse response) {
super(response);
}
@Override
public String encodeURL(final String url) {
String encurl = super.encodeURL(url).replaceAll(
";jsessionid=[0-9a-zA-Z]+", "");
return encurl;
}
}
@Override
public void init(final FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(final ServletRequest request,
final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
if (response instanceof HttpServletResponse
&& !(response instanceof CutJsessionidResponseWrapper)) {
chain.doFilter(request, new CutJsessionidResponseWrapper(
(HttpServletResponse) response));
return;
}
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
web.xml
<filter>
<filter-name>cutJsessionidFilter</filter-name>
<filter-class>ex.web.interceptor.CutJsessionidFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cutJsessionidFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
JSPで色々やっている場合はINCLUDEの指定も必要になる場合があります。
Apache Tiles を使用しており、テンプレートからJSPを埋め込んでいたため対応が必要でした。
懐かしさもある話かと思いますが、Tilesの罠に気づかず意外と時間を取られたので。
結論
Servlet 3.0を使おう!