不同线程上的 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的主要内容,如果未能解决你的问题,请参考以下文章
为啥实时 AppEngine 没有调用我的 servlet 过滤器?
App Engine上的Django vs webapp2 [关闭]