0 java google-app-engine servlets jetty static-members
我有一个应用程序,其中Servlet有一个方法调用Update(ReqIn, ReqOut).我从doGet&调用它doPost并传递Request和Response变量,然后Update(...)填写以下静态变量:
...
public class Server extends HttpServlet {
public static HttpServletRequest In = null;
public static HttpServletResponse Out = null;
public static boolean isDebug = true;
public static boolean isPost = false;
public static String URL = "";
public static String IP = "0.0.0.0";
public static Cookie[] Cookies = null;
public static UserClass User = null;
public static boolean isLoggedIn = false;
...
}Run Code Online (Sandbox Code Playgroud)
基本上抽象最常用的东西并在每次请求时更新它.这也允许我从网站的任何地方访问IP地址和当前用户数据,只需Server.User.getUsername();编写每次加载页面时使用新的类实例并使用更长的访问代码:Server.getUser().getUsername();
现在的问题是:当在多用户环境(AppEngine上的Jetty)时,这会引入任何问题吗?例如,一些线程/赛车问题使用户看到不正确的IP地址,或者在极端情况下突然以不同的用户身份登录?
或者我应该重写代码并将其更改为Public UserClass User代替Public static UserClass User等?
使用静态是一个非常糟糕的主意,因为如果你同时收到两个请求,那么它们就会相互叠加.以这个简单的例子来看看会出现什么问题:
1:public class Server extends HttpServlet {
2: public static int requestNo = 0;
3: public void doGet(HttpServletRequest req, HttpServletResponse resp)
4: {
5: requestNo++;
6: resp.getWriter().println(requestNo);
7: }
8:}
Run Code Online (Sandbox Code Playgroud)
现在想象以下时间表:
请求1进入,并处理最多,包括第5行.
请求2进入,并完全处理.
请求1继续处理.
两个请求都将获得文本"2",而不是一个获得"1"而一个获得"2".这是一个被踩踏的状态的简单例子.
现在,回答你问题的第二部分;
或者我应该重写代码并将其更改为Public UserClass User而不是Public static UserClass User等?
不,这也不够好,因为J2EE规范允许servlet容器使用类的一个实例来服务该servlet映射的所有请求,也就是说,实例级变量将具有与存在完全相同的效果静态,它们在所有请求之间共享.
这只留下三个真正的选择:
是的,这是一个非常糟糕的主意!
如果您同时收到两个请求,您会发生什么?每个静态变量只能包含一个值,因此您将丢失数据.
您可以使用,ThreadLocal以便每个线程只能访问它正在处理的当前请求/用户/等 - 但这仍然是一个坏主意.它很脆弱,隐藏了较低层需要信息的事实.将状态传递给需要它的代码.
| 归档时间: |
|
| 查看次数: |
5126 次 |
| 最近记录: |