JSF2与GAE和ViewScoped ManagedBean

Tho*_*hor 5 java google-app-engine primefaces jsf-2

在本教程之后,我设法使用JSF2获得了Googles AppEngine的工作原型.现在我对ViewScoped ManagedBean有一些奇怪的行为:

@ManagedBean @ViewScoped
public class TestBean implements Serializable
{
  private String text;         //getter/setter
  private List<String> texts;    //getter

  @PostConstruct public void init() 
  {
    texts = new ArrayList<String>();
    texts.add("Test");
    text = new String();
  }

  public void save(ActionEvent ae)
  {  
    texts.add(text);
    text = new String();
  }
}
Run Code Online (Sandbox Code Playgroud)

这是我的.xhtml页面:

<h:body id="body">
  <f:view contentType="text/html">
     <h:form id="frm">
        <p:panel>  
            <h:panelGrid columns="2" id="grid">   
                <p:inputText value="#{testBean.text}"/>  
                <p:commandButton value="Add" update=":frm:op @parent"
                                actionListener="#{testBean.save}" />   
            </h:panelGrid>
        </p:panel>
        <p:outputPanel id="op">
           <p:dataTable var="v" value="#{testBean.texts}">  
              <p:column><h:outputText value="#{v}" /></p:column>
           </p:dataTable>
        </p:outputPanel>
     </h:form>
  </f:view>
</h:body>
Run Code Online (Sandbox Code Playgroud)

这适用于本地部署(使用GAE的Eclipse工具),但如果我将其部署到GAE,如果单击Add -Button 则没有任何反应.使用范围(GAE)的其他测试在单击" 添加"后显示以下内容:

  • @RequestScoped:输入的文本不会消失,也不会添加到dataTable
  • @ViewScoped:输入的文本不会消失,也不会添加到dataTable
  • @SessionScoped:输入文本消失,dataTable始终有两个条目:"测试"和最后输入的文本

我从教程中得到了相同的设置

<context-param>  //web.xml
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>server</param-value>
</context-param>

//appengine-web.xml
<sessions-enabled>true</sessions-enabled>
Run Code Online (Sandbox Code Playgroud)

更新1

以下是带@ManagedBean @ViewScoped注释的其他测试的结果:

在第一次请求(或手动刷新页面)期间,@PostConstruct init()调用该方法.如果我点击按钮没有发生任何事情,请求test.jsf记录在应用程序引擎日志中,但我的save()方法中没有记录.Firebug向我显示POST请求test.jsf和以下答案:

<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error>
  <error-name>class javax.faces.application.ViewExpiredException</error-name>
  <error-message>
     <![CDATA[viewId:/test.jsf - View /test.jsf could not be restored.]]>
  </error-message>
  </error>
  <extension primefacesCallbackParam="validationFailed">
    {"validationFailed":false}
  </extension>
</partial-response>
Run Code Online (Sandbox Code Playgroud)

更新2

我使用过mojarra-2.0.4但现在更新到2.0.6.同样的问题,但一个新的观察:如果我清除所有的Firefox缓存,ViewExpiredException没有出现,但我只能添加1个元素List<String>.该@PostConstruct只调用一次,而不是为按钮每次点击.

然后我尝试了myfaces-2.0.7,但得到了这个例外:

Uncaught exception from servlet
java.lang.NoClassDefFoundError: Could not initialize class
com.google.apphosting.runtime.security.shared.stub.javax.naming.InitialContext
Run Code Online (Sandbox Code Playgroud)

我不确定我是否应该尝试让myfaces工作,因为谷歌在他们的教程中明确提到了mojarra(2.0.4).

参考

Tho*_*hor 3

通常我不会回答我的问题,我只将此答案视为解决方法,而不是正确答案。如果我不喜欢保存客户端状态,这似乎可以解决奇怪的行为。但我必须详细检查一下:

<context-param>
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>client</param-value>
</context-param>
Run Code Online (Sandbox Code Playgroud)

也许我们应该等到JAVASERVERFACES-1886得到解决。