Appengine Filter和Servlet在不同的线程上

时间:2015-03-13 10:20:55

标签: java multithreading google-app-engine servlets servlet-filters

我正在尝试为我的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());
    }

2 个答案:

答案 0 :(得分:0)

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

因此,让它按照您希望的方式工作的一种方法是将User对象附加到终点的线程局部变量。在过滤器和结束点本身之间,您可以将用户作为请求范围变量进行传输。

答案 1 :(得分:0)

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

request.setAttribute("user", user);

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

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