【问题标题】:How do I keep track of the session for each servlet request, until I use it? Singletons wont work?在使用之前,如何跟踪每个 servlet 请求的会话?单身人士不会工作?
【发布时间】:2011-02-21 14:54:47
【问题描述】:

对于我收到的每个 servlet 请求,我可能会通过 10 个方法,然后我需要检查会话中的某些内容并且我需要 HttpSession。

我能获得 HttpSession 的唯一方法是从 HttpServletRequest,对吗?

如何跟踪每个 servlet 请求的会话?不幸的是,我不能简单地创建一个单例(例如,SessionInformation.instance().getAttribute("name")),因为该会话将用于所有请求。

有没有办法为每个请求全局存储会话,而不必将它(或它的信息)传递给所有方法,以防万一我需要它?

更新 1:

Alohci 把我推向了正确的方向。我需要的东西可以:

1) 设法仅通过线程全局存储变量。 “单线程”解决方案?

2) 或者 servlet 获得的每个线程/请求是否有唯一的 ID?如果有,是什么?

【问题讨论】:

  • 说实话。正确的方法是传递信息。你的应用程序不应该太复杂,以至于它必须向下发送 10 种方法。谢谢大家。

标签: java google-app-engine session servlets


【解决方案1】:

如何跟踪会话 每个 servlet 请求?

服务器通过在浏览器上保存会话 ID 的 cookie 标记用户来识别用户。在服务器上,会话是您放置在客户端/服务器交互期间需要跟踪的数据的位置(以向应用程序提供状态)。

session.setAttribute("name", SerializableObject)

注意:因为 App Engine 将会话数据存储在数据存储区和内存缓存中,所以存储在会话中的所有值都必须实现 java.io.Serializable 接口。

然后您可以通过执行从 HttpServletRequest 中获取会话

request.getSession()

参见 javadoc:here

在 servlet 中检索会话后,您可以使用 session.getAttribute("name") 检索您感兴趣的任何数据以跟踪交互。

有没有办法为每个请求全局存储会话

当唯一具有访问会话的 ID 是收到带有该会话 ID 的请求的 servlet 时,为什么要全局存储它。并非您的应用程序中的所有内容都需要了解每个请求。

以下是带有会话 ID cookie 的 请求 示例:

GET /something.htm HTTP/1.1     
Accept: www/source     
Accept: text/html     
Cookie: sessid=123456789

您不能全局存储此信息,它对每个请求都是唯一的。

不用过关

在对数据做有用的事情时,不要将会话传递给你的方法,传递有用的信息,比如用户名、购物车内容等。

HttpSession session = request.getSession() //inside a servlet
String userName = session.getAttribute("name");
List<ShoppingItems> items= session.getAttribute("cart");

MakeTheUserPay(userName, items) //no session passing here

您的业务逻辑方法甚至不应该知道会话是什么。它更像是一件人工制品。

【讨论】:

  • 您写道“并非应用程序中的所有内容都需要了解每个请求。” - 如果我开始在每种方法中传递数据,这正是会发生的事情。我想要的是在我需要从会话中获取名称时使用类似“SessionInformation.instance().getAttribute("name"))”的东西。我不想阅读并将名称发送给“可能”使用它的每个“页面”。
  • "如果我开始在每个方法中传递数据,这正是会发生的事情。如果我开始在每个方法中传递数据,这正是会发生的事情。" --- 你不要把它传递到它不会被使用的地方。 “我不想阅读并将名称发送给每个“可能”使用它的“页面”。 --- 您将对象传递给将需要它的代码部分。这样做有什么问题?
  • 就我个人而言,我一直尝试做通用的事情。例如,我的网站有“页面”(一个实现接口 Page 的类),它为我所做的每个页面/请求执行逻辑和呈现。但并不是所有页面都需要存储在会话中的“用户名”,那么为什么我在调用页面时总是要发送它呢?我更愿意在该特定页面中执行“String username = SessionInformation.instance().getUserName()”,而不是始终将其作为方法参数发送。
  • @bakkal 我也想做同样的事情,你找到解决这个问题的方法了吗?
【解决方案2】:

我认为你想要的是一个 java.lang.ThreadLocal 变量。

【讨论】:

【解决方案3】:

我认为您需要使用 Context object 在表示层和业务层之间传递状态(我假设存在一个)。

Context 对象使您能够封装状态并将其跨层传递,而不必担心如何维护状态本身。如果您需要获得这方面的更多信息,可以参考 Core J2EE 模式一书中的上下文对象设计模式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 2015-09-25
    • 2014-08-08
    相关资源
    最近更新 更多