1

概括

在我们的 Web 应用程序中,当用户点击“比页面加载更快”时,显然浏览器向用户显示了第一个请求(根据我们得到的一些错误消息)。我原以为这是第二个请求。

更多背景信息

我们有一个 Struts1 Web 应用程序。在用户会话中,我们放置了用户交互的当前上下文。

request.getSession().setAttribute("context", <something>);

例如,应用程序显示主记录列表,上下文包含有关用户的信息。当用户单击主记录时,我们将有关该记录的信息保存在用户会话对象中。在 JSP 中,我们经常将上下文对象分配给一个局部变量。这需要转换为特定类型(例如MasterRecordDTOor UserDTO):

<% MasterRecordDTO dto = (MasterRecordDTO) request.getSession().getAttribute("context"); %>

然后,用户可以深入了解该主记录的详细信息视图。我们有一个显示 sth like 的面包屑list > master > detail。这些是链接,因此用户可以使用面包屑导航。

现在,当在这种情况下,用户首先单击“master”并且足够快地单击“list”时,他会收到一个 ClassCastException 说

"UserDTO cannot be cast to MasterRecordDTO" 

在 MasterRecord-JSP 中,这意味着当 MasterRecord-JSPdto在第一次请求中分配变量时,第二次请求已经将会话context属性设置为UserDTO对象。

问题

我原以为浏览器会“放弃”第一个请求并向用户显示第二个请求的结果(本例中的主记录列表)。有人可以向我解释一下吗?

更新

面包屑链接位于另一个 HTML 框架中。我们在 Internet Explorer 7 上遇到了这个问题。我在 Firefox 11 上进行了尝试,但显然它甚至没有提交第二次点击。

4

1 回答 1

0

我猜这是一般的并发编程情况。

浏览器同时向服务器发送 2 个请求,服务器使用 2 个线程处理 2 个请求。

  1. 请求/线程 1 将会话属性设置contextMasterRecordDTO
  2. 请求/线程 2 然后将其更改为UserDTO这是问题的根源
  3. 请求/线程 1 继续运行,会导致ClassCastException发生。
  4. 请求/线程 2 继续运行,它将向客户端生成成功的响应。(但浏览器不显示)

浏览器的行为不受您的应用程序控制,它只是显示响应 1 的结果(有时可能是响应 2,这也是并发情况,因为当前大多数浏览器都是多线程设计的)。

尝试使用请求范围来存储此类context信息以获得预期的结果。

于 2012-06-07T08:45:09.050 回答