在POJO外部容器中检索servlet上下文,会话和请求

有没有办法从POJO中检索会话? 或者最终从POJO中检索bean。

澄清:

基本上我是从servlet创建一个bean,我需要从Web容器外部(从POJO)访问该bean的属性。 我无法将请求传递给pojo; 并且需要请求来检索会话。

更具体地说,我有一个Web应用程序,它使用Cactus框架从Web界面运行JUnit测试。 但是,调用JUnit测试运行器的servlet是在jar中编译的; 我添加了额外的下拉菜单来更改JUnit测试将从中读取的设置以在不同环境(WLI集群)之间切换,因此,如果已经编译了运行器servlet,我无法修改它以处理来自多个环境的额外参数。 我已经尝试了写入.dat文件的持久性方法,JUnit测试将通过Reader类读取该文件; 我也尝试过最终无法通过JUnit测试访问的bean方法。

只有当您的POJO在运行HttpServletRequest同一个线程中运行时,您才能在ThreadLocal帮助下实现此目的。

创建以下类:

 public final class YourContext implements AutoCloseable { private static ThreadLocal instance = new ThreadLocal<>(); private HttpServletRequest request; private HttpServletResponse response; private YourContext(HttpServletRequest request, HttpServletResponse response) { this.request = request; this.response = response; } public static YourContext create(HttpServletRequest request, HttpServletResponse response) { YourContext context = new YourContext(request, response); instance.set(context); return context; } public static YourContext getCurrentInstance() { return instance.get(); } @Override public void close() { instance.remove(); } public HttpServletRequest getRequest() { return request; } public HttpSession getSession() { return request.getSession(); } public ServletContext getServletContext() { return request.getServletContext(); } // ... (add if necessary more methods here which return/delegate the request/response). } 

实现javax.servlet.Filter ,它在doFilter()方法中doFilter()以下操作,并映射到感兴趣的url-pattern ,例如/*或前控制器servlet的servlet-name

 @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; try (YourContext context = YourContext.create(request, response)) { chain.doFilter(request, response); } } 

请注意try-with-resources语句的重要性。 它保证在filter完成其作业后将调用YourContext#close()并清除ThreadLocal资源。 否则,线程在为另一个HTTP请求回收时仍会包含它。

以下是如何在POJO中使用它:

 YourContext context = YourContext.getCurrentInstance(); HttpSession session = context.getSession(); 

这一切基本上也是普通MVC框架的Context对象的工作原理,比如JSF的FacesContext和Wicket中的那个。

说,你看过CDI吗? 也许更容易制作CDI管理的工件,这样你就可以@Inject他们彼此。

Pojo是一个普通的旧Java对象。 POJOS与会话无关。

https会话在请求对象上可用。

看看这个

http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/api/index.html

特别是HttpServletRequest接口和getSession()方法。

对于问题的“bean”部分。 bean是符合3个标准的java类。

  1. 没有arg构造函数
  2. setter和getters访问私有字段
  3. 实现可序列化。

如果POJ遵循这些约定,则它是一个bean。

假设您指的是Servlet编程….

从POJO到Session没有直接的方法。 您需要从HttpServletRequest对象获取Session。

我见过有两种流行的解决方案可以解决这个问题。

第一个选项是创建包含Session的某种上下文对象。 然后将此上下文传递到您的业务层,以便您的POJO可以在需要时获取此信息。

第二种选择是利用ThreadLocal存储。 通常,会话通过filter或拦截器放置在ThreadLocal存储上。 然后系统中的任何对象都可以从线程中获取它。 这种模式出现在许多Web框架中,如Spring和Struts。

就在这里。

如果您正在使用Web框架,例如Wicket,通常有一种方法可以获得当前的HttpSession。 从那里,你可以获得Spring ApplicationContext,如果你有,你可以从中获得Spring Beans。 这适用于任何位置,因为我们只使用静态实用程序方法。

示例代码:

 import org.apache.wicket.protocol.http.WebApplication; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.context.WebApplicationContext; ServletContext sc = WebApplication.getServletContext(); WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc); Object bean = wac.getBean("myBeanId"); 

但请注意,Spring Filter和Wicket Filter必须就位并处理当前请求,否则实用程序方法将不起作用。

如果你不是指Spring Bean,那么你必须自己将它们存储在HTTP Session中。 如果您没有Web框架,您可能希望执行rfeak建议并实现您自己的ThreadLocal。