Java Servlet 中静态变量的使用(例如在 AppEngine 中)

发布于 2024-08-14 04:30:52 字数 1080 浏览 3 评论 0原文

我有一个应用程序,其中 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;


    ...
}

基本上抽象最常用的东西和内容。根据每个请求更新它。这也允许我访问 IP 地址和网站中任何位置的当前用户数据,只需编写 Server.User.getUsername(); 而不是每次加载页面时创建一个新的 Class 实例并使用更长的访问代码:Server .getUser().getUsername();

现在的问题是:在多用户环境(AppEngine 上的 Jetty)中,这会带来任何问题吗?例如,一些线程/竞赛问题导致用户看到不正确的 IP 地址,或者在极端情况下突然以不同用户身份登录?

或者我应该重写代码并将其更改为 Public UserClass User 而不是 Public static UserClass User 等?

I have an application where Servlet has a method called Update(ReqIn, ReqOut). I call it from doGet & doPost and pass the Request and Response variables, and it is then up to Update(...) to fill out the following static variables:

...
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;


    ...
}

Basically Abstracting most used stuff & updating it on every request. This also allows me to access IP address & current user data from anywhere in the website, by writting just Server.User.getUsername(); insead of making a new Class instance everytime a page is loaded and using much longer access code: Server.getUser().getUsername();

Now the question is: When in multi user environment (Jetty on AppEngine), can this introduce any problems? E.g. some threading/racing issues making user see incorrect IP address or in extreme case suddenly being logged in as different user?

Or should I rewrite code and change it to Public UserClass User instead of Public static UserClass User, etc?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

无人问我粥可暖 2024-08-21 04:30:52

使用静态是一个非常糟糕的主意,因为如果您同时收到两个请求,那么它们将互相覆盖。通过这个简单的例子来看看可能会出现什么问题:

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:}

现在想象一下以下时间线:

请求 1 进入,并处理到第 5 行(包括第 5 行)。
请求 2 进入并完成处理。
请求 1 继续处理。

两个请求都将获得文本“2”,而不是一个获得“1”,一个获得“2”。这是国家被践踏的一个简单例子。

现在,回答你问题的第二部分;

或者我应该重写代码并将其更改为 Public UserClass User 而不是 Public static UserClass User 等?

不,这还不够好,因为 J2EE 规范允许 servlet 容器使用类的一个实例来服务该 servlet 映射的所有请求,也就是说,实例级变量将具有与静态数据,它们在所有请求之间共享。

这只剩下三个真正的选择:

  1. 将所有内容放入 HTTPSession。这里的问题是,这是一个地图,所以你失去了类型安全,并且很难看出东西在哪里使用。
  2. 创建一个 Holder 类来保存所有状态并将其传递到各处。这好一点,因为至少你不会失去类型安全,但你仍然没有完全的可见性。
  3. 传递个人所需的物品。

Using statics is a hugely bad idea, since if you get two requests come in at the same time then they will write over each other. Take this trivial example to see what can go wrong:

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:}

Now imagine the following timeline:

Request 1 comes in, and processes up to, and including, line 5.
Request 2 comes in, and processes completely.
Request 1 continues processing.

Both requests will get the text "2", instead of one getting "1" and one getting "2". This is a simple example of the state being stomped on.

Now, to answer the second part of your question;

Or should I rewrite code and change it to Public UserClass User instead of Public static UserClass User, etc?

No, that is also not good enough, since the J2EE spec allows the servlet container to use one instance of a class to service all of the requests for that servlet mapping, that is, the instance level variables will have exactly the same effect as being statics, they are shared between all requests.

This leaves only three real options:

  1. Shove everything into HTTPSession. The problem here is that this is a map, so you lose type safety, and it is difficult to see where things are being used.
  2. Create a Holder class to hold all of your state and pass that around everywhere. This is a little better, since at least you don't lose the type safety, but you still don't have full visibility either.
  3. Pass the individual required items around.
二智少女 2024-08-21 04:30:52

是的,这是一个非常糟糕的主意!

如果您同时收到两个请求,您期望会发生什么?每个静态变量只能保存一个值,因此您将丢失数据。

可以使用ThreadLocal 这样每个线程只能访问它正在处理的当前请求/用户/等 - 但这基本上仍然是一个坏主意。它很脆弱,并且隐藏了较低层需要信息的事实。将状态传递给需要它的代码。

Yes, this is a hugely bad idea!

What would you expect to happen if you got two requests at the same time? Each static variable can only hold one value, so you're going to lose data.

You could use ThreadLocal so that each thread only had access to the current request/user/etc that it was dealing with - but that's still basically a bad idea. It's brittle, and hides the fact that lower layers need the information. Pass the state down to the code that needs it instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文