在容器外的 POJO 中检索 servlet 上下文、会话和请求 [英] Retrieving servlet context, session and request in a POJO outside container

查看:20
本文介绍了在容器外的 POJO 中检索 servlet 上下文、会话和请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is there any way to retrieve a session from a POJO? Or ultimately to retrieve a bean from a POJO.

澄清:

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

Basically I am creating a bean from a servlet and I need to access the properties of that bean from outside of the web container (from a POJO). I cannot pass the request to the pojo; and the request is needed to retrieve the session.

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

More specifically I have a web application that uses the Cactus framework to run JUnit tests from a web interface. However the servlet that invokes the JUnit test runner is compiled in a jar; I added extra drop down menus to change settings from which the JUnit test will read from to switch between different environments (WLI clusters), so given that the runner servlet is already compiled I cannot modify it to handle the extra parameters from the multiple environments. I have tried the persistence approach of writing to a .dat file fro which the JUnit test will read from by way of a Reader class; also I have have tried the bean approach which ultimately was not accessible from the JUnit test.

推荐答案

仅当您的 POJO 与 HttpServletRequest 运行在 相同 线程中运行时,那么您将能够在 的帮助下实现这一目标ThreadLocal.

Only and only if your POJO is running in the same thread as the HttpServletRequest is running in, then you'll be able to achieve this with help of 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 的 servlet-name 上.

Implement javax.servlet.Filter which does the following in doFilter() method and is mapped on an url-pattern of interest, e.g. /* or on the servlet-name of your front controller 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 请求回收时仍将包含它.

Note the importance of try-with-resources statement. It guarantees that the YourContext#close() will be called after the filter has done its job and the ThreadLocal resource will be cleared. Otherwise the thread will still contain it when recycled for another HTTP request.

以下是在 POJO 中使用它的方法:

And here's how you could use it in the POJO:

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

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

This all is basically also how the Context objects of the average MVC framework works, like JSF's FacesContext and the one in Wicket.

说了这么多,你有没有看CDI?或许让 CDI 管理的工件更容易,这样您就可以@Inject 将它们相互插入.

Said that, have you looked at CDI? Perhaps it's easier to make the artifacts CDI-managed so you can just @Inject them in each other.

这篇关于在容器外的 POJO 中检索 servlet 上下文、会话和请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆