Java 我可以在web.xml中关闭HttpSession吗?

Java 我可以在web.xml中关闭HttpSession吗?,java,session,web-applications,web.xml,Java,Session,Web Applications,Web.xml,我想完全消除HttpSession—我可以在web.xml中这样做吗?我确信有一些特定于容器的方法可以做到这一点(这就是我在谷歌搜索时会聚集搜索结果的原因) 这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们 我想完全消除HttpSession—我可以在web.xml中这样做吗?我相信有一些特定于容器的方法可以做到这一点 我不这么认为。禁用HttpSession将违反Servlet规范,该规范规定HttpServletRequest#getSession应返回或创建一个会话。所以我不希望J

我想完全消除HttpSession—我可以在web.xml中这样做吗?我确信有一些特定于容器的方法可以做到这一点(这就是我在谷歌搜索时会聚集搜索结果的原因)

这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们

我想完全消除HttpSession—我可以在web.xml中这样做吗?我相信有一些特定于容器的方法可以做到这一点

我不这么认为。禁用
HttpSession
将违反Servlet规范,该规范规定
HttpServletRequest#getSession
应返回或创建一个会话。所以我不希望JavaEE容器提供这样的配置选项(这会使它不兼容)

这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们

嗯,我真的不明白,只是如果你不想使用它,就不要在会话中放任何东西。现在,如果您确实想阻止会话的使用,可以使用
过滤器
将请求替换为
HttpServletRequestWrapper
覆盖
getSession()
的实现。但我不会浪费时间来实现这一点:)


更新:我最初的建议不是最佳的,正确的(咳嗽)方法是替换请求。

您可以使用URL重写筛选器重写URL,而不是禁用。这将提供谷歌友好的结果,但仍然允许基于cookie的会话处理

然而,您可能应该对所有响应禁用它,因为这比搜索引擎不友好更糟糕。它公开可用于的会话ID

对于Tuckey过滤器:

<outbound-rule encodefirst="true">
  <name>Strip URL Session ID's</name>
  <from>^(.*?)(?:\;jsessionid=[^\?#]*)?(\?[^#]*)?(#.*)?$</from>
  <to>$1$2$3</to>
</outbound-rule>

删除URL会话ID
^(.*)(:;jsessionid=[^\?\]*)?(\?[^\\]*)?(\?[^\\]*))?(#*)$
$1$2$3
我想完全消除HttpSession

你不能完全禁用它。您需要做的只是而不是通过
request.getSession()
request.getSession(true)
在Web应用程序代码中的任意位置获取它的句柄,并通过设置
确保JSP不会隐式地这样做

如果您主要关心的是禁用在
HttpSession
后台使用的cookie,那么您可以在Java EE 5/Servlet 2.5中仅在特定于服务器的webapp配置中这样做。例如,在Tomcat中,您可以在
元素中将
cookies
属性设置为
false

<Context cookies="false">
如果要在Web应用程序中硬编码,以便
getSession()
永远不会返回
HttpSession
(或“空”的
HttpSession
),然后,您需要创建一个过滤器,侦听
/*
url模式,该模式将
HttpServletRequest
替换为一个返回所有
getSession()
方法
null
的实现,或者一个不执行任何操作的伪自定义
HttpSession
实现,甚至抛出
不支持操作异常

@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);
}

这是个坏主意吗?在我真正需要它们之前,我宁愿完全禁用它们


如果你不需要它们,就不要使用它们。这就是全部。真的:)

对于RESTful应用程序,我只是在每次请求生命周期结束时使其失效。可能有一些web服务器在新客户端访问时总是创建新会话,无论您是否调用
request.getSession()

我对我的RESTful应用程序使用以下方法来删除任何无意中创建和使用的会话cookie


1.
0
但是,这并不能完全关闭HttpSessions。应用程序仍可能无意中创建会话,即使它在一分钟内消失,并且恶意客户端也可能忽略cookie的最大年龄请求


这种方法的优点是不需要更改应用程序,只需
web.xml
。我建议您创建一个
HttpSessionListener
,它将记录会话的创建或销毁时间,以便您可以跟踪会话的发生时间。

无法避免会话的创建。但是,您可以在请求周期结束时检查您是否违反了自己的要求。因此,创建一个简单的servlet过滤器,将其放在chain的前面和后面。如果创建了会话,doFilter将抛出一个异常:

chain.doFilter(request, response);
if(request.getSession(false) != null)
    throw new RuntimeException("Somewhere request.getSession() was called");

如果您正在构建无状态高负载应用程序,您可以禁用使用cookie进行会话跟踪,如下所示(非侵入性,可能与容器无关):

并将其添加到web.xml中,并修复因该异常而失败的位置:

<listener>
    <listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>

com.ideas.bucketlist.web.PreventSessionListener

在带有Java配置的Spring Security 3中,您可以使用HttpSecurity.sessionManagement():

Xml看起来像这样

<http create-session="stateless">
  <!-- config -->
</http>

顺便说一下,NEVER和无状态的区别

从不:Spring Security不会创建HttpSession,但会使用 HttpSession(如果已存在)将被删除

无状态:Spring安全性永远不会创建HttpSession,而且它会 切勿使用它来获取SecurityContext


从Servlet 3.0开始,您可以通过向
ServletContextListener的
contextInitialized
方法添加这样的代码,使Servlet容器不会以任何方式跟踪会话:

servletContext.setSessionTrackingModes(Collections.emptySet());

这是一个多么有趣的问题。我遇到的情况是,使用Tomcat时,没有为我创建会话,因此我正在搜索是否有办法在web.xml中打开会话:dthttpservletrequestwrapper
听起来不错,我同意。在一个有许多开发人员的大型项目中,您需要执行一些架构决策(比如无状态)。你不能仅仅依靠人们“不使用它”,“如果你不需要他们,就不要使用他们”这并不是那么简单。数百个天秤座中的一些
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");
}
}
<listener>
    <listener-class>com.ideas.bucketlist.web.PreventSessionListener</listener-class>
</listener>
@Override
protected void configure(final HttpSecurity http) throws Exception {
    http
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
<http create-session="stateless">
  <!-- config -->
</http>
servletContext.setSessionTrackingModes(Collections.emptySet());