【问题标题】:JSF2 with GAE and ViewScoped ManagedBean带有 GAE 和 ViewScoped ManagedBean 的 JSF2
【发布时间】:2011-11-02 14:15:16
【问题描述】:

按照tutorial,我设法获得了一个带有 JSF2 的原型,开始在 Google 的 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();
  }
}

这是我的 .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>

这适用于本地部署(使用 GAE 的 Eclipse 工具),但如果我将它部署到 GAE,如果我单击 Add-Button,则不会发生任何事情。单击添加后,范围内的附加测试(在 GAE)显示以下内容:

  • @RequestScoped:输入的文字没有消失,没有添加到dataTable中
  • @ViewScoped:输入的文本没有消失,没有添加到数据表中
  • @SessionScoped: Entered Text 消失,dataTable 始终有两个条目:“Test”和最后输入的 Text

我在教程中有相同的设置

<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>

更新 1

以下是带有@ManagedBean @ViewScoped 注解的附加测试结果:

在第一次请求(或手动刷新页面)期间,调用@PostConstruct init() 方法。如果我点击按钮 nothing happes,对test.jsf 的请求会记录在应用引擎日志中,但我的save() 方法中没有日志。 Firebug 向我显示了对 test.jsf 的 POST 请求和以下答案:

<?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>

更新 2

我使用过 mojarra-2.0.4,但现在更新到 2.0.6。同样的问题,但有一个新的观察:如果我清除所有 Firefox 缓存,ViewExpiredException 不会出现,但我只能向List&lt;String&gt; 添加 1 个元素。 @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

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

参考文献

【问题讨论】:

  • 您能否从开发人员的角度而不是从最终用户的角度详细说明“什么都没有发生”?像 Firebug 这样的 HTTP 流量调试器是怎么说的? ajax POST 请求是否被发送?究竟返回了什么响应? bean 的操作方法是否被调用?设置器是否被调用? bean 不是根据同一视图的每个请求不必要地(后)构建的吗?等等。打开调试器或通过在打印信息和/或感兴趣的变量的战略位置输入一堆System.out.println() 行来进行穷人的调试。
  • 亲爱的 BalusC,您说的完全正确。我将添加调试信息。感谢您指出这一点(并为 Firebug 记住我)!
  • 哈,你有一个ViewExpiredException。现在沸腾得很好。下一个问题,您使用的是 MyFaces 还是 Mojarra?什么版本?我记得以前在 GAE 上的某个版本的 MyFaces 上看到过这种问题。无论如何,尝试将 JSF impl/version 升级到 GAE 支持的最新版本。 Mojarra 目前对于 Servlet 2.5 容器是 2.0.6,对于 Servlet 3.0 容器是 2.1.2(我不做 GAE,但我想它仍然支持最大 Servlet 2.5)。 MyFaces 分别位于 2.0.7 和 2.1.1。
  • 我发现了一个类似的 SO 问题:stackoverflow.com/questions/4813946/viewexpiredexception

标签: java google-app-engine jsf-2 primefaces


【解决方案1】:

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

<context-param>
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>client</param-value>
</context-param>

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-22
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 2013-11-20
    相关资源
    最近更新 更多