在Java EE系统中编写静态实用程序类

Eng*_*uad 3 java jsp servlets ejb jakarta-ee

我想开发一个实用程序类,可以以静态方式(静态方法)用于企业 Java 系统(JSP、Servlet、EJB)。它包含一些能够访问HttpSession用户对象并检索一些已存储为属性的有用信息(例如当前用户 ID)的方法。

你们中的一些人可能想知道为什么我需要这样的东西,而我可以简单地将HttpSession对象传递到任何地方。实际上,我正在开发旧版 Java EE 5.0 系统,一些实用程序类(不是 Servlet、JSP 或 EJB)无法访问该HttpSession对象。

是否可以实现这样的实用程序类?我/你应该在这里考虑一些限制:

  • Servlet/JSP 托管在与托管 EJB 不同的计算机上。
  • 该系统运行在Weblogic 10.3.0上。
  • 在 weblogic 上,有许多服务器(托管 servlet/JSP)并且它们位于同一个集群下。EJB 服务器也是如此。
  • 如果我Collection在实用程序类中声明一些静态,它会起作用吗?或者由于存在多个类加载器和多个 JVM,因此可能会有多个副本?
  • 也许我应该使用共享文件或共享数据库来实现它?我怎样才能跟踪哪个用户调用了实用程序类?也许跟踪线程?或者可能是与交易相关的事情?

Bal*_*usC 6

利用ThreadLocal. 您不应该HttpSession直接将其存储在那里。服务层不应该对javax.servletAPI有任何依赖。相反,直接从 中提取所需的信息HttpSession并将其存储在那里。

例如,当您想要将User的属性公开HttpSession为线程局部变量时:

public class SomeContext {

    private static ThreadLocal<SomeContext> instance = new ThreadLocal<SomeContext>();
    private User user;

    private SomeContext(User user) {
        this.user = user;
    }

    public static SomeContext getCurrentInstance() {
        return instance.get();
    }

    public static SomeContext newInstance(User user) {
        SomeContext someContext = new SomeContext(user);
        instance.set(someContext);
        return someContext;
    }

    public void release() {
        instance.remove();
    }

    public User getUser() {
        return user;
    }

}
Run Code Online (Sandbox Code Playgroud)

这是servlet 过滤器doFilter()中的:

User user = (User) request.getSession().getAttribute("user");
SomeContext someContext = SomeContext.newInstance(user);

try {
    chain.doFilter(request, response);
} finally {
    // It's very important to do this in finally!
    // Threads are namely pooled by the container.
    someContext.release();
}
Run Code Online (Sandbox Code Playgroud)

在特定过滤器之后在同一线程中运行的任何代码(包括 EJB)中,您可以获得User如下结果:

User user = SomeContext.getCurrentInstance().getUser();
// ...
Run Code Online (Sandbox Code Playgroud)