不同线程上的 Appengine 过滤器和 Servlet

Posted

技术标签:

【中文标题】不同线程上的 Appengine 过滤器和 Servlet【英文标题】:Appengine Filter and Servlet on different Threads 【发布时间】:2015-05-15 18:56:49 【问题描述】:

我正在尝试为我的 appengine 应用实施过滤器。过滤器对用户进行身份验证并将当前用户保存在 THREAD_LOCAL 变量中。问题是运行过滤器的线程与运行 servlet 的线程不同。这是 appengine 的正常行为还是我做错了什么?

这是我的过滤器:

@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());

【问题讨论】:

这绝对不是您通过将经过身份验证的用户保存在 THREAD_LOCAL 变量中引入的行为。但除此之外,为什么你必须这样做?为什么不只是在请求范围内? 我想在我的代码中的任何地方访问 currentuser 表单,以便我可以检查他在任何类中的角色和访问级别。我知道通过请求范围提交它可能是更好且更省钱的解决方案,但以这种方式处理它也更复杂且耗时。 过滤器链中还有其他过滤器吗? 我只有一个过滤器,那就是 ObjectifyFilter 【参考方案1】:

一些容器具有“执行线程”,它只是为请求生成新线程并返回侦听新线程。但是一旦到达终点(一个 Servlet),几乎所有的请求处理都发生在执行 Servlet 的线程中。

因此,使其按您希望的方式工作的一种方法是将 User 对象附加到端点的线程局部变量。在过滤器和端点本身之间,您可以将 User 作为请求范围的变量。

【讨论】:

【参考方案2】:

如果您想为当前请求保存用户,请执行以下操作:

request.setAttribute("user", user);

并通过 API 方法执行此操作以获取用户:

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

【讨论】:

以上是关于不同线程上的 Appengine 过滤器和 Servlet的主要内容,如果未能解决你的问题,请参考以下文章

App Engine 上未调用 Servlet 过滤器

为啥实时 AppEngine 没有调用我的 servlet 过滤器?

App Engine上的Django vs webapp2 [关闭]

Golang、App Engine、通道和线程安全

Android 到服务器上的 Appengine RPC Nullponter

appEngine 中 Django 的最新示例