ViewExpiredException, когда я использую @ViewScoped

У меня проблема с моим h: commandButton «Вход»: когда я использую @ViewScoped и нажимаю эту кнопку, возникает ViewExpiredException, но когда я использую @SessionScoped, ошибки нет.

Трассировки стека:

javax.faces.application.ViewExpiredException: /pages/register.xhtmlNo saved view state could be found for the view identifier: /pages/register.xhtml
at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:132)
at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
at org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:45)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)

моя страница:

            <h:form>
                <h:panelGrid columns="2" >
                    <h:outputLabel value="Login:"/>
                    <h:inputText value="#{registerController.registerLog}"/>
                    <h:outputLabel value="#{msg.password}"/>
                    <h:inputSecret id="pass" value=""/>

                    <h:column/>
                    <h:commandButton value="Login" action="#{registerController.login}"/> 

                </h:panelGrid> 
            </h:form>

и это мой класс RegisterController:

@ManagedBean
@ViewScoped
public class RegisterController {

private String registerLog = "";
private String registerPass = "";


/**
 * Creates a new instance of RegisterController
 */
public RegisterController() {
}

//getters, setters

public String login(){

    return null;

}

person kuba44    schedule 13.09.2013    source источник
comment
Вы проверили stackoverflow.com/questions/10535227/?   -  person noone    schedule 13.09.2013
comment
да, но это не помогает   -  person kuba44    schedule 13.09.2013
comment
Пусть ваш компонент implements Serializable и повторите попытку. Это решает проблему или нет? Исключение, кстати, вводит в заблуждение для этой проблемы, но MyFaces по умолчанию всегда сериализует состояние просмотра, даже если включено сохранение состояния на стороне сервера, так что вы никогда не знаете.   -  person BalusC    schedule 13.09.2013
comment
да, это решит проблему. Спасибо :) А в чем проблема? Почему я должен реализовывать Serializable?   -  person kuba44    schedule 13.09.2013
comment
Я получаю эту ошибку, и мой bean-компонент реализует Serializable... мысли?   -  person Seth M.    schedule 30.04.2014
comment
@СетМ. - Удалось починить? Это случилось со мной, и я не могу понять это. Я нашел это - myfaces.apache.org/wiki/core/user-guide/jsf-and-myfaces-howtos/ описывает мой случай, но я понятия не имею как это исправить из этой статьи.   -  person Anton    schedule 26.01.2015
comment
@Anton посмотрите на ответ BalusC ниже   -  person kuba44    schedule 26.01.2015
comment
@ kuba44 Ну, все это было сделано после первого поиска в Google :) Если вы посмотрите на ссылку, которую я разместил, она предлагает немного другой сценарий. Я не знаю, заслуживает ли это еще одного поста на SO, но я решил это, добавив httpssessionfilter по тайм-ауту, чтобы перенаправить меня на вход в систему, а не восстанавливать состояние просмотра.   -  person Anton    schedule 26.01.2015


Ответы (2)


Ваша конкретная проблема вызвана тем, что ваш компонент с областью видимости не сериализуем, и, следовательно, MyFaces не может сохранить его в состоянии просмотра. MyFaces по умолчанию сериализует все состояние в сеансе вместо того, чтобы просто ссылаться на состояние в сеансе и иметь контейнер для его сериализации, если это необходимо.

Есть в основном 2 решения:

  1. Пусть ваш bean-компонент с областью видимости реализует Serializable.

  2. Скажите MyFaces не сериализовать все состояние просмотра в сеансе.

    <context-param>
        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    

    Обратите внимание, что bean-компонент с областью видимости все равно будет потерян при каждом перезапуске сервера.

person BalusC    schedule 13.09.2013

http://arjan-tijms.omnifaces.org/p/jsf-22.html#1127

В реализации MyFaces JSF2.1 org.apache.myfaces.SERIALIZE_STATE_IN_SESSION по умолчанию было true, а в Mojarra com.sun.faces.serializeServerState по умолчанию было false.


Начиная с JSF2.2, это будет стандартизировано через javax.faces.SERIALIZE_SERVER_STATE, который по умолчанию равен false.

<context-param>
    <param-name>javax.faces.SERIALIZE_SERVER_STATE</param-name>
    <param-value>true</param-value>
</context-param>
person Chacko Mathew    schedule 02.11.2013