我可以closuresweb.xml中的HttpSession吗?
我想完全消除HttpSession – 我可以在web.xml中做到这一点? 我确定有容器特定的方法来做到这一点(这是search结果,当我做一个谷歌search)。
PS这是一个坏主意? 我宁愿完全禁用,直到我真正需要它们。
我想完全消除HttpSession
你不能完全禁用它。 你只需要在你的web应用代码的任何地方通过request.getSession()或者request.getSession(true)来处理它,并且确保你的JSP不隐式地通过设置<%@page session="false"%> 
 如果您主要关心的是实际禁用在HttpSession后面使用的cookie,那么您可以在Java EE 5 / Servlet 2.5中仅在特定于服务器的webappconfiguration中进行此操作。 在例如Tomcat中,你可以在<Context>元素中设置cookies属性为false 。 
 <Context cookies="false"> 
另请参阅此Tomcat的特定文档 。 通过这种方式,会话将不会被保留在随后的请求中,这些请求不是URL重写的 – 只有当您由于某种原因从请求中获取请求时才会使用它。 毕竟,如果你不需要它, 只是不抓住它,那么它将不会被创build/保留。
 或者,如果您已经使用了Java EE 6 / Servlet 3.0或更高版本,并且真的想通过web.xml来实现,那么您可以使用web.xml新的<cookie-config>元素如下进行清零最大年龄: 
 <session-config> <session-timeout>1</session-timeout> <cookie-config> <max-age>0</max-age> </cookie-config> </session-config> 
 如果你想在你的web应用程序中进行硬编码,这样getSession()永远不会返回一个HttpSession (或者一个“空的” HttpSession ),那么你需要创build一个监听/*的url-pattern的filter,该url-pattern将HttpServletRequestreplace为HttpServletRequestWrapper实现返回所有getSession()方法的null ,或者一个虚拟的自定义的HttpSession实现,它什么也不做,甚至抛出UnsupportedOperationExceptionexception。 
 @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); } 
PS这是一个坏主意? 我宁愿完全禁用,直到我真正需要它们。
如果你不需要它们,就不要使用它们。 就这样。 真的:)
我使用以下方法为我的REST风格的应用程序删除任何无意的会话cookie被创build和使用。
 <session-config> <session-timeout>1</session-timeout> <cookie-config> <max-age>0</max-age> </cookie-config> </session-config> 
但是,这并没有完全closuresHttpSession。 会话仍然可能由应用程序无意中创build,即使它在一分钟内消失,并且stream氓客户端也可能会忽略cookie的最大年龄请求。
 这种方法的优点是你不需要改变你的应用程序,只需要web.xml 。 我build议你创build一个HttpSessionListener ,它会在会话创build或销毁时logging日志,以便跟踪它何时发生。 
如果你正在构build一个无状态的高负载应用程序,你可以像这样禁用cookies来进行会话跟踪(非侵入式的,可能是容器不可知的):
 <session-config> <tracking-mode>URL</tracking-mode> </session-config> 
为了执行这个架构决定写这样的事情:
 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"); } } 
并将其添加到web.xml中,并修复出现该exception的地方:
 <listener> <listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class> </listener> 
而不是禁用,你可以重写URL使用URL重写filter,例如tuckey重写filter 。 这将给谷歌友好的结果,但仍然允许基于cookie的会话处理。
但是,您应该禁用所有响应,因为它不仅仅是不友好的search引擎。 它暴露了可用于某些安全漏洞的会话ID。
Tuckeyfilter的configuration示例 :
 <outbound-rule encodefirst="true"> <name>Strip URL Session ID's</name> <from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from> <to>$1$2$3</to> </outbound-rule> 
我想完全消除HttpSession – 我可以在web.xml中做到这一点? 我确定有容器特定的方法来做到这一点
 我不这么认为。 禁用HttpSession将违反Servlet规范,该规范声明HttpServletRequest#getSession应返回会话或创build一个会话。 所以我不希望Java EE容器提供这样的configuration选项(这会使其不符合规范)。 
这是一个坏主意吗? 我宁愿完全禁用,直到我真正需要它们。
 那么,我真的不明白这一点,如果你不想使用它,就不要在会议中join任何东西。 现在,如果你真的想阻止会话的使用,你可以使用一个Filter来replace请求,用一个HttpServletRequestWrapper实现覆盖getSession() 。 但我不会浪费时间来实现这个:) 
更新:我最初的build议不是最佳的,“正确”( 咳嗽 )的方式是取代请求。
 对于REST式应用程序,每当请求的生命周期结束时,我都会将其无效化。 无论您调用request.getSession()还是不调用,都可能有一些Web服务器始终会在新客户端访问时创build新会话。 
在具有Java Config的Spring Security 3中,可以使用HttpSecurity.sessionManagement():
 @Override protected void configure(final HttpSecurity http) throws Exception { http .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS); } 
Xml看起来像这样;
 <http create-session="stateless"> <!-- config --> </http> 
顺便说一句,从来没有和STATELESS的区别
永远不会:spring安全将永远不会创build一个HttpSession,但将使用HttpSession,如果它已经存在
STATELESS:Spring Security永远不会创build一个HttpSession,它永远不会使用它来获取SecurityContext
一个不能避免创build会话。 但是您可以在请求周期结束时检查是否违反了您自己的要求。 因此,创build一个简单的servletfilter,将其作为第一个放置,然后在链接.doFilter创build会话后抛出exception:
 chain.doFilter(request, response); if(request.getSession(false) != null) throw new RuntimeException("Somewhere request.getSession() was called");