JSP / Servlet设计问题 – 通过JNDI全局提供请求/响应

在PHP中,总是能够从代码的任何部分访问当前请求或响应。 这个概念是PHP编程的基础。 请求数据,响应数据,会话数据(等)始终存在

这在Java Servlets中不会发生! 为了能够访问代码中的HttpServletRequest,HttpServletResponse,HttpSession(等),您需要将它们作为函数变量传递。 这意味着您无法对本质上“知道”所有这些内容的Web框架进行编码,并消除了传递它们的复杂性。

所以,我设计了这个解决方案:

  1. 创建anf注册ServletRequestListener。
  2. requestInitialized事件将当前的HttpServletRequest绑定到JNI上下文,给出当前Thread的名称(Thread.currentThread()。getName());
  3. 在requestDestroyed事件解除绑定上面的JNI资源以进行清理。

这样,可以从代码的任何位置访问当前请求/响应,因为它们始终存在于JNI上下文中,并且可以通过提供当前线程的名称来检索。

所有已知的servlet容器都为每个请求实现单线程模型 ,因此请求无法混淆(当然,不能忘记清理它们)。

此外,每个Web应用程序的JNI资源在默认情况下是分开的 ,因此不存在混淆它们的问题或者可能由访问其他Web请求的Web应用程序引起的安全问题。

有点扭曲,但又好又简单……

你怎么看?

我认为一些Web框架(GWT,Axis)已经这样做了,但是以更简单的方式:通过使用ThreadLocal静态变量(或者可以从单例访问)。 Spring也有这种可能性。

不过,我不确定它是否适用于所有容器。 如果容器使用非阻塞IO并重用相同的线程来并行处理多个请求,则它将不再起作用。

请参阅从Java代码中获取HttpServletRequest(request)对象以获取类似问题(及其答案)。

如果你担心不同的请求搞砸了(然后考虑像模型窗口那样的“子请求”),或许你更愿意考虑使用Seam ? 他们使用一种称为“Session”的抽象来处理很多开发人员试图用其他传统Web技术堆栈破解的东西。 Seam建立在JSF上,就像fyi一样。 您不必使用EJB 3或Hibernate,但它也可以很好地与这两者集成。 需要考虑的事情。