I would like to eliminate the HttpSession completely - can I do this in web.xml? I\'m sure there are container specific ways to do it (which is what crowds the search result
If you are building a stateless high load application you can disable using cookies for session tracking like this (non-intrusive, probably container-agnostic):
<session-config>
<tracking-mode>URL</tracking-mode>
</session-config>
To enforce this architectural decision write something like this:
public class PreventSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
throw new IllegalStateException("Session use is forbidden");
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
throw new IllegalStateException("Session use is forbidden");
}
}
And add it to web.xml and fix places where it fails with that exception:
<listener>
<listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
As of Servlet 3.0, you can make it so sessions are not tracked by the servlet container in any way, by adding code like this to the contextInitialized
method of a ServletContextListener
:
servletContext.setSessionTrackingModes(Collections.emptySet());
Javadoc.
I would like to eliminate the HttpSession completely - can I do this in web.xml? I'm sure there are container specific ways to do it
I don't think so. Disabling the HttpSession
would be a violation of the Servlet spec which states that HttpServletRequest#getSession
should return a session or create one. So I wouldn't expect a Java EE container to provide such a configuration option (that would make it non compliant).
Is this a bad idea? I prefer to completely disable things until I actually need them.
Well, I don't really get the point, just don't put anything in the session if you don't want to use it. Now, if you really want to prevent the use of the session, you can use a Filter
to replace the request with a implementation of HttpServletRequestWrapper
overriding getSession()
. But I wouldn't waste time implementing this :)
Update: My initial suggestion was not optimal, the "right" (cough) way would be to replace the request.
One cannot avoid the session creation. But you can check if you violate your own requirement at the end of a request cycle. So, create a simple servlet filter, which you place as first and after chain.doFilter throw an exception if a session was created:
chain.doFilter(request, response);
if(request.getSession(false) != null)
throw new RuntimeException("Somewhere request.getSession() was called");
In Spring Security 3 with Java Config, you can use HttpSecurity.sessionManagement():
@Override
protected void configure(final HttpSecurity http) throws Exception {
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
Xml looks like this;
<http create-session="stateless">
<!-- config -->
</http>
By the way, the difference between NEVER and STATELESS
NEVER:Spring Security will never create an HttpSession, but will use the HttpSession if it already exists
STATELESS:Spring Security will never create an HttpSession and it will never use it to obtain the SecurityContext
I would like to eliminate the HttpSession completely
You can't entirely disable it. All you need to do is to just not to get a handle of it by either request.getSession()
or request.getSession(true)
anywhere in your webapplication's code and making sure that your JSPs don't implicitly do that by setting <%@page session="false"%>
.
If your main concern is actually disabling the cookie which is been used behind the scenes of HttpSession
, then you can in Java EE 5 / Servlet 2.5 only do so in the server-specific webapp configuration. In for example Tomcat you can set the cookies
attribute to false
in <Context>
element.
<Context cookies="false">
Also see this Tomcat specific documentation. This way the session won't be retained in the subsequent requests which aren't URL-rewritten --only whenever you grab it from the request for some reason. After all, if you don't need it, just don't grab it, then it won't be created/retained at all.
Or, if you're already on Java EE 6 / Servlet 3.0 or newer, and really want to do it via web.xml
, then you can use the new <cookie-config>
element in web.xml
as follows to zero-out the max age:
<session-config>
<session-timeout>1</session-timeout>
<cookie-config>
<max-age>0</max-age>
</cookie-config>
</session-config>
If you want to hardcode in your webapplication so that getSession()
never returns a HttpSession
(or an "empty" HttpSession
), then you'll need to create a filter listening on an url-pattern
of /*
which replaces the HttpServletRequest
with a HttpServletRequestWrapper implementation which returns on all getSession()
methods null
, or a dummy custom HttpSession
implementation which does nothing, or even throws UnsupportedOperationException
.
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new HttpServletRequestWrapper((HttpServletRequest) request) {
@Override
public HttpSession getSession() {
return null;
}
@Override
public HttpSession getSession(boolean create) {
return null;
}
}, response);
}
P.S. Is this a bad idea? I prefer to completely disable things until I actually need them.
If you don't need them, just don't use them. That's all. Really :)