在J2EE WebFilter过滤器中使用静态方法是否安全?

时间:2016-12-31 17:34:43

标签: servlets java-ee java.util.concurrent

我想知道它是否安全(没有死锁的可能性)在J2ee web过滤器中使用静态方法,或者我应该使用实例方法? 我有以下doFilter方法

 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
     HttpServletRequest httpServletRequest = (HttpServletRequest) request;
     HttpServletResponse httpServletResponse = (HttpServletResponse) response;
     String contextPath = httpServletRequest.getContextPath();
     if ((httpServletRequest.getRequestedSessionId() != null &&
             !httpServletRequest.isRequestedSessionIdValid()) || (loginBean == null || loginBean.getUserId() == -1)) {
         httpServletResponse.sendRedirect(contextPath + Navigation.getLoginURL());


     } else {
         chain.doFilter(request, response);
     }
 }

哪里

  

Navigation.getLoginURL()

是一种静态方法。这可能导致僵局吗?

1 个答案:

答案 0 :(得分:1)

这是静态方法的要点是不依赖于Filter实例的状态;整个应用程序的登录URL是相同的。由于没有保护状态,没有理由锁定任何东西。

在静态方法中调用一些锁定的东西(如System.out.println)并不意味着你的代码会死锁。实现api servlet和过滤器的Java EE代码应避免执行大量锁定,因为它需要支持高级别的并发性。

从实施者的角度来看这应该可以帮助您确定可以安全地调用的内容,请参阅Java Concurrency in Practice,第4.5.1节(解释模糊文档)中的引用:

  

你将不得不猜测。提高猜测质量的一种方法是从实施它的人(例如容器或数据库供应商)的角度解释规范,而不是仅仅使用它的人。 Servlet总是从容器管理的线程调用,可以安全地假设如果有多个这样的线程,容器就知道这一点。 servlet容器使某些对象可以为多个servlet提供服务,例如HttpSession或ServletContext。因此,servlet容器应该期望同时访问这些对象,因为它已经创建了多个线程并从中调用了Servlet.service等方法,这些方法可以合理地期望访问ServletContext。

     

由于无法想象这些对象有用的单线程上下文,因此必须假设它们已经成为线程安全的,即使规范没有明确要求这样做。此外,如果他们需要客户端锁定,客户端代码应该在什么锁上同步?文档没有说,猜测似乎很荒谬。规范和官方教程中的示例进一步证明了这种“合理的假设”,它们展示了如何访问ServletContext或HttpSession,并且不使用任何客户端同步。