2009-12-04 62 views
0

我有一個應用程序,其中Servlet有一個名爲Update(ReqIn, ReqOut)的方法。我把它從doGet & doPost並傳遞請求和響應變量,它然後由Update(...)填寫以下靜態變量:在Java Servlets中使用靜態變量(例如在AppEngine中)

... 
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(); INSEAD做一個新的類實例每次頁面加載並使用更長的訪問代碼:Server.getUser().getUsername();

現在的問題是:當在多用戶環境(AppEngine上的Jetty)時,可以引入任何問題嗎?例如。一些線程/競速問題使用戶看到不正確的IP地址,或者在極端情況下突然以不同的用戶身份登錄?

或者我應該重寫代碼並將其更改爲Public UserClass User而不是Public static UserClass User等?

回答

7

使用靜態是一個非常糟糕的主意,因爲如果你有兩個請求在同一時間進入,那麼他們會寫對方。把這個簡單的例子,看看有什麼可以去錯了:

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行
請求2進來,並完全處理。
請求1繼續處理。

這兩個請求都會得到文本「2」,而不是一個獲得「1」和一個獲得「2」。這是國家被踩踏的一個簡單例子。

現在,回答你的問題的第二部分;

或者我應該重寫代碼並將其更改爲Public UserClass User而不是Public static UserClass User等?

不,那也不夠好,因爲J2EE規範允許servlet容器使用類的一個實例來服務所有該servlet映射的請求,也就是實例級變量將有與靜態效果完全相同,它們在所有請求之間共享。

這讓只有三個真正的選擇:

  1. 肖夫萬事成的HTTPSession。這裏的問題是這是一張地圖,所以你會失去類型安全性,很難看到事物被使用的地方。
  2. 創建一個Holder類來保存你所有的狀態,並將它傳遞給每個地方。這樣會好一點,因爲至少你不會失去類型安全性,但是你仍然沒有完全可見性。
  3. 傳遞個別需要的物品。
6

是的,這是一個非常糟糕的主意!

如果您同時收到兩個請求,您會如何期望?每個靜態變量只能保存一個值,所以你會丟失數據。

可以使用ThreadLocal這樣每個線程只有獲取當前的請求/用戶/等,它處理的是 - 但是這主要還是一個壞主意。它很脆弱,隱藏了低層需要這些信息的事實。將狀態傳遞給需要它的代碼。

+0

@Downvoter:小心給個理由?使用靜態是不好的,或者你可能*(但不應該)使用ThreadLocal? – 2009-12-07 11:32:00

+0

servlet傳入請求和響應對象以捕獲處理特定請求的狀態。爲什麼要存儲一個靜態副本來處理請求?或者,爲什麼要在請求之間存儲靜態副本?這不是一個明智的做法。 – 2009-12-11 17:08:15

+0

@JonSkeet(順便說一句,與你同意。) – 2009-12-11 17:08:57