0

我試圖爲我的appengine應用程序實現一個過濾器。過濾器驗證用戶並將當前用戶保存在THREAD_LOCAL變量中。問題是運行過濾器的線程與運行servlet的線程不同。這是appengine的正常行爲還是我做錯了什麼?Appengine過濾器和Servlet在不同的線程

這是我的過濾器:

@Override 
public void doFilter(ServletRequest request, ServletResponse response, 
     FilterChain chain) throws IOException, ServletException { 
    try { 
     Session.removeCurrentSession(); 
     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     SessionFactory.authorize(httpRequest.getHeader("Authorization")); 
     System.out.println("Filter ThreadId: " + Thread.currentThread().getId()); 
     chain.doFilter(request, response); 
     System.out.println("Filter ThreadId: " + Thread.currentThread().getId()); 
    } 
    finally { 
     Session.removeCurrentSession(); 
    } 
} 

,這是我的AppEngine上登錄端點:

@ApiMethod(name = "users.login", path = "login", httpMethod = HttpMethod.POST) 
      public Message loginUser(HttpServletRequest request) throws UnauthorizedException { 

       System.out.println("Servlet ThreadId: " + Thread.currentThread().getId()); 
       Session session = Session.getCurrentSession(); 
       System.out.println("Session: "+ session.getId() + " ThreadId: " + Thread.currentThread().getId()); 
    } 
+1

這絕對不是一個行爲,你通過將認證用戶保存在THREAD_LOCAL變量中來引入。但是,除此之外,爲什麼你必須這樣做呢?爲什麼不只是在請求範圍內? – ramp 2015-03-13 10:39:52

+0

我想訪問我的代碼中的任何地方的currentuser表單,以便我可以檢查他的角色和訪問級別的任何類。我知道通過請求範圍提交它可能是更好和更省錢的解決方案,但以這種方式處理它也更加複雜且花費時間。 – Weini 2015-03-13 11:12:57

+0

你有沒有其他的過濾器鏈內的過濾器? – 2015-03-13 11:36:56

回答

0

一些容器已「執行線程」剛剛生成新線程的請求並返回監聽新的。但是一旦達到了一個終點(一個Servlet),幾乎所有的請求處理都發生在執行Servlet的線程中。

所以一種使它按照你想要的方式工作的方法是將User對象附加到終點的線程局部變量。在篩選器和結束點本身之間,您可以將用戶作爲請求作用域變量進行傳輸。

0

如果你想保存當前請求的用戶,這樣做:

request.setAttribute("user", user); 

,並從API方法做到這一點對於獲得用戶:

public ApiResponse apiMethod(HttpServletRequest request) { 
    User user = (User) request.getAttribute("user");