JSP/Servlet 设计问题 - 通过 JNDI 使请求/响应全局可用
在 PHP 中,人们总是能够从其代码的任何部分访问当前请求或响应。这个概念是 PHP 编程的基础。 请求数据、响应数据、会话数据(等)始终存在!
这在 Java Servlet 中不会发生!为了在代码中访问 HttpServletRequest、HttpServletResponse、HttpSession(等),您需要将它们作为函数变量传递。这意味着您无法编写一个本质上“了解”所有这些内容并消除传递它们的复杂性的 Web 框架。
所以,我设计了这个解决方案:
- 创建并注册一个ServletRequestListener。
- 在 requestInitialized 事件发生时,将当前 HttpServletRequest 绑定到以当前线程名称给出的 JNI 上下文 (Thread.currentThread().getName());
- 在 requestDestroyed 事件发生时,取消绑定上述 JNI 资源以进行清理。
这样,人们就可以从代码的任何位置访问当前请求/响应,因为它们始终位于 JNI 上下文中,并且可以通过提供当前线程的名称来检索。
所有已知的servlet容器都为每个请求实现了单线程模型,因此请求不可能混合在一起(当然不能忘记清理它们)。
此外,默认情况下,每个 Web 应用程序的 JNI 资源都是分离的,因此无需担心将它们混合在一起,也不必担心一个 Web 应用程序访问该资源可能会引起安全问题。其他人的要求。
有点扭曲,但是很好很简单......
你觉得怎么样?
In PHP one is always able to access the current request or response from any part of their code. This concept is fundamental to PHP programming. Request data, response data, session data (etc) are always there!
This does not happen in Java Servlets! In order to have access to the HttpServletRequest, HttpServletResponse, HttpSession (etc) in your code you need to pass them around as function variables. This means that you cannot code a web framework that inherently "knows" about all these and removes the complexity of passing them around.
So, I have devised this solution:
- Create anf register a ServletRequestListener.
- Upon the requestInitialized event bind the current HttpServletRequest to the JNI context giving in the name of the current Thread (Thread.currentThread().getName());
- Upon the requestDestroyed event unbind the above JNI resource to cleanup.
This way one has access to the current request/response from any place of their code, since they are always there in the JNI context and can be retrieved by providing the current thread's name.
All known servlet container implement the single-thread model for each request, so there is no way for the requests to get mixed up (of course one must not forget to clean them up).
Also the JNI resources of each web application are separated by default so there are no concerns of mixing them up or of security issues that could arise from one web application having access to the requests of the others.
Kinda twisted, but nice and simple...
What do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为一些 Web 框架(GWT、Axis)已经做到了这一点,但是以一种更简单的方式:通过使用 ThreadLocal 静态变量(或从单例访问)。 Spring也有这种可能。
不过,我不确定它是否适用于所有容器。如果容器使用非阻塞IO并重用同一个线程来并行处理多个请求,那就不行了。
请参阅从 Java 代码获取 HttpServletRequest(请求)对象类似的问题(及其答案)。
I think some web frameworks (GWT, Axis) already do that, but in a much simpler way: by using a ThreadLocal static variable (or accessible from a singleton). Spring also has this possibility.
I'm not sure it works with all the containers, though. If the container uses non-blocking IO and reuses the same thread to handle multiple requests in parallel, it won't work anymore.
See Get the HttpServletRequest (request) object from Java code for a similar question (and its answers).
如果您担心不同的请求会混乱(然后像模型窗口一样考虑“子请求”),也许您宁愿考虑使用 接缝?他们使用称为“会话”的抽象来处理我们开发人员尝试使用其他传统 Web 技术堆栈进行破解的许多事情。 Seam 是基于 JSF 构建的,仅供参考。您不必将 EJB 3 或 Hibernate 与它一起使用,但它也可以与这两者很好地集成。值得思考的事情。
If you are worried about different requests getting messed up (and then think about "sub requests" like a model window), perhaps you'd rather think about using Seam? They use an abstraction called a "Session" to handle a LOT of the things that we developers try to hack around with other traditional web technology stacks. Seam is built on JSF just as an fyi. You don't have to use EJB 3 or Hibernate with it, but it does integrate nicely with both of those as well. Something to think about.