小编典典

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

jsp

有什么方法可以从POJO中检索会话?或者最终从POJO中检索bean。

澄清:

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

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


阅读 264

收藏
2020-06-08

共1个答案

小编典典

仅且仅当POJO与运行中的线程在 同一
线程HttpServletRequest中运行时,您才能在的帮助下实现此目标ThreadLocal<T>

创建以下类:

public final class YourContext implements AutoCloseable {

    private static ThreadLocal<YourContext> 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.FilterdoFilter()方法中执行以下操作并映射到url- pattern感兴趣的对象(例如,/*或在servlet-name您的前端控制器servlet上)的实现。

@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语句的重要性。它保证YourContext#close()在过滤器完成其工作并且ThreadLocal将清除资源后将调用。否则,线程在为另一个HTTP请求回收时仍将包含它。

这是在POJO中使用它的方式:

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

这基本上也是Context普通MVC框架的对象的工作方式,例如JSF
FacesContext和Wicket中的对象。

话说回来,您看过CDI吗?使工件进行CDI管理也许更容易,所以您可以将@Inject它们相互配合。

2020-06-08