I want to develop a utility class, that can be used in a static manner (static methods), for an enterprise Java system (JSP, Servlets, EJBs). It'd contain some methods that is capable to access the HttpSession
object of the user and retrieves some useful info that is already stored as attributes (such as the current user id).
我想开发一个实用程序类,它可以以静态方式(静态方法)用于企业Java系统(JSP,Servlets,EJB)。它包含一些能够访问用户的HttpSession对象的方法,并检索一些已经存储为属性的有用信息(例如当前用户ID)。
Some of you may wonder why do I need such thing, while I can simply passing the HttpSession
object to anywhere. Actually, I am working on a legacy Java EE 5.0 system and some of the utility classes (not Servlets, JSPs, nor EJBs) have no access to the HttpSession
object.
有些人可能想知道为什么我需要这样的东西,而我可以简单地将HttpSession对象传递到任何地方。实际上,我正在研究遗留的Java EE 5.0系统,并且一些实用程序类(不是Servlet,JSP或EJB)无法访问HttpSession对象。
Is it possible to implement such utility class? Some constraints I/you should consider here:
有可能实现这样的实用类吗?我/你应该考虑一些限制:
- The servlets/JSPs are hosted on machines that are different from what host EJBs.
- servlet / JSP托管在与主机EJB不同的机器上。
- The system is running on Weblogic 10.3.0.
- 该系统在Weblogic 10.3.0上运行。
- On weblogic, there are many servers (that host servlets/JSPs) and they are under the same cluster. The same thing is with EJBs servers.
- 在weblogic上,有许多服务器(托管servlet / JSP),它们位于同一个集群下。 EJB服务器也是如此。
- If I declare some static
Collection
inside the utility class, is it going to work? or maybe there will be more than one copy of it because of the multiple class loaders and multiple JVMs? - 如果我在实用程序类中声明了一些静态Collection,它会起作用吗?或者由于多个类加载器和多个JVM,可能会有多个副本?
- Maybe I should use a shared file or shared database to implement it? How even could I track which user invokes the utility class? Maybe tracking the thread? or maybe something related to the transaction?
- 也许我应该使用共享文件或共享数据库来实现它?我怎么能跟踪哪个用户调用实用程序类?也许跟踪线程?或者与交易有关的事情?
2 个解决方案
#1
4
Make use of ThreadLocal
. You should only not store the HttpSession
directly in there. The service layer should not have any dependency on javax.servlet
API. Instead, extract the desired information from the HttpSession
directly and store it there.
使用ThreadLocal。你不应该直接在那里存储HttpSession。服务层不应该对javax.servlet API有任何依赖。相反,直接从HttpSession中提取所需信息并将其存储在那里。
E.g. when you want to expose User
attribute of the HttpSession
as a thread local variable:
例如。当您想要将HttpSession的User属性公开为线程局部变量时:
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;
}
}
and this in doFilter()
of a servlet filter:
这在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();
}
in any code which is running in the very same thread after the particular filter, including EJBs, you can get the User
as follows:
在特定过滤器(包括EJB)之后的同一个线程中运行的任何代码中,您可以按如下方式获取User:
User user = SomeContext.getCurrentInstance().getUser();
// ...
#2
1
The HttpSession is local to a Thread.
HttpSession是Thread的本地。
Do you really need an HttpSession or could you just do what you want with a static ThreadLocal attribute?
你真的需要一个HttpSession,或者你可以用静态ThreadLocal属性做你想做的事吗?
See: http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
请参阅:http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
btw, Apache Shiro uses this class to store some "Session" information.
顺便说一下,Apache Shiro使用这个类来存储一些“Session”信息。
#1
4
Make use of ThreadLocal
. You should only not store the HttpSession
directly in there. The service layer should not have any dependency on javax.servlet
API. Instead, extract the desired information from the HttpSession
directly and store it there.
使用ThreadLocal。你不应该直接在那里存储HttpSession。服务层不应该对javax.servlet API有任何依赖。相反,直接从HttpSession中提取所需信息并将其存储在那里。
E.g. when you want to expose User
attribute of the HttpSession
as a thread local variable:
例如。当您想要将HttpSession的User属性公开为线程局部变量时:
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;
}
}
and this in doFilter()
of a servlet filter:
这在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();
}
in any code which is running in the very same thread after the particular filter, including EJBs, you can get the User
as follows:
在特定过滤器(包括EJB)之后的同一个线程中运行的任何代码中,您可以按如下方式获取User:
User user = SomeContext.getCurrentInstance().getUser();
// ...
#2
1
The HttpSession is local to a Thread.
HttpSession是Thread的本地。
Do you really need an HttpSession or could you just do what you want with a static ThreadLocal attribute?
你真的需要一个HttpSession,或者你可以用静态ThreadLocal属性做你想做的事吗?
See: http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
请参阅:http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html
btw, Apache Shiro uses this class to store some "Session" information.
顺便说一下,Apache Shiro使用这个类来存储一些“Session”信息。