SessionScoped Beans在(快速)双击

时间:2017-02-19 00:31:10

标签: jsf cdi jsf-2.2 session-scope

环境:

omnifaces 2.6

mojarra 2.2.12

焊接servlet的2.2.9

tomcat 8

和最小的bean设置:

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named("test")
@SessionScoped
public class TestBean implements Serializable {

private static final long serialVersionUID = -2697121845047289456L;


   @PostConstruct
   public void init(){
     System.out.println("TestBean.init()");     
   }
}

test.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">        

    #{test}

</ui:composition>

启动tomcat后,快速请求页面 test.xhtml (GET)多次会导致以下控制台输出:

TestBean.init()
TestBean.init()
TestBean.init()
TestBean.init()

使用jsf-annotations替换cdi时会发生相同的行为:

@ManagedBean(name="test")
@javax.faces.bean.SessionScoped
public class TestBean implements Serializable {
}

任何想法是由于如何解决这个问题造成的?



更新 我刚刚用一个全新的项目重现了这种行为,以确保我的代码或配置中没有任何污染。仅包括最新的mojarra 2.2.14和tomcat 8.0.36。拖动链接

localhost:8080/SessionBeanTest/test 

到浏览器栏并在tomcat启动时开始快速点击此链接。你会看到相同的输出。 如何阻止为同一请求创建多个会话?

package test;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class SessionCounter implements HttpSessionListener {

    private static int count;

   @Override
    public void sessionCreated(HttpSessionEvent event) {
        System.out.println("session created: " + event.getSession().getId());
        count++;
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent event) {
        System.out.println("session destroyed: " + event.getSession().getId());
        count--;
    }

    public static int getCount() {
        return count;
    }
}

的web.xml

 <listener><listener-class>test.SessionCounter</listener-class>

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean(name="test")
@SessionScoped
public class TestBean implements Serializable {

   private static final long serialVersionUID = -1L;

   @PostConstruct
   public void init(){
     HttpServletRequest request =  (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
      System.out.println("TestBean.init() with requested session-id: " + request.getRequestedSessionId());
   }

   public Integer getTotalSessions(){
     return SessionCounter.getCount();
   }
}

test.xhtml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"      
  xmlns:h="http://java.sun.com/jsf/html">

<h:head>
    <title>SessionBean-Test</title>
</h:head>
<h:body>    
    <h2>#{test.totalSessions}</h2>
</h:body>

输出快速点击4次:

session created: 85473180423E40234184E2B748A3BF65
session created: 984C12EAF08B8A427C23B8CA98C6EF10
session created: DA147A440A9D03860B110E8AD063B548
session created: 577261D977E090D3E67E35DB55A97CD5
TestBean.init() with requested session-id: D385B49654C289FE41E718BE3BC9F5FA
TestBean.init() with requested session-id: D385B49654C289FE41E718BE3BC9F5FA
TestBean.init() with requested session-id: D385B49654C289FE41E718BE3BC9F5FA
TestBean.init() with requested session-id: D385B49654C289FE41E718BE3BC9F5FA

0 个答案:

没有答案