Мне удалось получить прототип с 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();
}
}
Это моя страница .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>
Это прекрасно работает с локальным развертыванием (с использованием инструментов Eclipse для GAE), но если я разверну это в GAE, ничего не произойдет, если я нажму кнопку Add . Дополнительные тесты с областью (в GAE) показывают следующее после нажатия на Добавить :
@RequestScoped
: введенный текст не исчезает, не добавляется в таблицу данных
@ViewScoped
: введенный текст не исчезает, не добавляется в таблицу данных
@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>
Обновление 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>
Обновление 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
Я не уверен, стоит ли пытаться заставить мои лица работать, так как Google явно упоминает mojarra (2.0.4) в их уроке.
Ссылки