【问题标题】:Should this class be in the ServletContext or session scoped in a JSP web applicaiton?此类应该在 JSP Web 应用程序中的 ServletContext 或会话范围内吗?
【发布时间】:2015-05-13 03:40:45
【问题描述】:

我正在开发一个 JSP Web 应用程序,以使用 HttpURLConnection 通过他们的 REST 服务从 Parse.com 数据库接收和传输数据。 Web 应用程序需要部署在 Google App Engine 或 Amazon Web Services 上。

我已经定义了一个 ParseUtils 类,它负责通过 HttpURLConnection 类从 Parse 数据库表中获取或发布数据。它有很多函数,每个函数都为特定的 Parse 表建立一个 HttpURLConnection。

希望我已根据需要提供了尽可能多的详细信息。我的问题是:ParseUtils 类应该在 ServletContext 初始化时在 ServletContext 中声明和初始化,还是应该定义为每个会话的会话范围对象?有什么最佳做法吗?

谢谢!

【问题讨论】:

  • 它是否包含任何特定于会话的状态?
  • 不,它没有。每个函数仅通过 URL 打开一个 HttpURLConnection,读取输入流,解析数据,将数据映射到数据模型。
  • 那么它应该进入应用范围。 (ServletContext)
  • 非常感谢蒂洛。
  • 如果两个用户同时登录应用并尝试调用 REST 服务怎么办?应用范围对象是否会阻塞网络流量或行为异常?

标签: java jsp servlets parse-platform servletcontextlistener


【解决方案1】:

连接对象在并发访问意义上通常不是“可共享的”(它们是可重复使用的,但是在托管环境/执行上下文中允许基于轮次的访问)。鉴于 HttpURLConnection is not threadsafe,没有理由将其保存在像 ServletContext 这样的全局共享状态组件中。

剩下的就是请求和会话范围,还需要回答以下问题

  1. 为每个请求建立一个新的HttpURLConnection 相关的开销是多少?
  2. 单个连接的客户端需要通过新窗口或标签打开两个管道(即单个会话中的两个 HttpURLConnections)的可能性/需求是什么?

#1 的答案是开销是存在的,但非常轻微;如果#2 的可能性很小,您肯定希望为每个请求打开一个新的HttpURLConnection,或者更好的是考虑使用Apache's HttpClient 以利用连接池之类的东西

【讨论】:

  • 目前 ParseUtils 在 ServletContextListener 中被初始化,只有几个配置。它不保持任何状态。每个 JSP 页面在加载时都会调用 ParseUtils 的一个函数来为不同的 Parse.com 表的不同 URL 打开一个新的 HttpURLConnection。我不认为为每个请求建立新连接会产生开销,或者这无关紧要。
  • 我不确定如果用户(会话 A)试图调用 ParseUtils 的函数来发布一些数据,而同时另一个用户试图调用相同的函数或使用另一个会话(会话 B)的不同功能。这些请求会排队吗?
  • 走安全路线并没有真正的缺点,即每个会话一个连接;为什么不保持安全? @alextc
【解决方案2】:

我不确定如果用户(会话 A)试图调用 ParseUtils 的函数来发布一些数据,而同时另一个用户试图使用另一个会话调用相同的函数或不同的函数会发生什么(会话 B)。这些请求会排队吗?

如果 ParseUtils 不在其实例变量中存储任何数据,那么您是绝对安全的。局部方法是线程安全的,只要不使用实例变量,就可以并发调用。

打个比方,想一想 Servlet 的单个实例如何处理多个请求。请求处理方法(doGet() 或 doPost())是 servlet 的本地方法,可同时访问以服务多个并行请求。只要您没有将可变请求数据存储在实例变量中,您就是安全的。

【讨论】:

  • 感谢坡道。实例变量在整个应用程序生命周期中只是配置和静态变量。所以这让我很安全。
猜你喜欢
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 2014-06-18
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
  • 1970-01-01
  • 2011-07-01
相关资源
最近更新 更多