4

フォームでいくつかのタブを開いたままにし、コマンド ボタンを押すと (セッションの有効期限が切れてからしばらくしてから)、次のような Java スクリプト アラートを受け取ります。

serverError: class javax.faces.application.ViewExpiredException viewId:/register.xhtml - ビュー /register.xhtml を復元できませんでした。

Firefox の場合 (ローカルで Glassfish 4)

私が追加しました :

<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/index.xhtml?faces-redirect=true</location>
</error-page>

web.xmlのインデックスにリダイレクトされません。何故ですか ?

編集:サンプルボタン

<h:commandButton value="Register" action="#{userController.register}">
    <f:ajax execute="@form" render="@form" />
</h:commandButton>

UserController は ViewScoped です

4

2 に答える 2

3

少なくともJSF-2.2 仕様のセクション 13.3.6.3 および 13.3.6.4 を見ると、これは予想される動作です。

<context-param>
  <param-name>javax.faces.PROJECT_STAGE</param-name>
  <param-value>Development</param-value>
</context-param>

web.xml(本番モードではエラーを黙って無視します)。そのボタンをクリックして受信すると、JSF クライアント側コードは AJAX 要求を送信します。

<error>
    <error-name>...</error-name>
    <error-message>...</error-message>
</error>

ViewExpiredException応答であなたと。クライアント側のコードは、そのエラー情報に反応することが期待されます。onerror(f:ajaxタグ上) またはaddOnError(jsf.ajaxオブジェクト上)で関数を登録して、自分でエラーを処理します。

多くの人は、サーバーがそのような問題についてクライアントに指示することを期待しているため、omnifaces には、基本的に応答をリセットし、指定したエラー ページを送信する FullAjaxExceptionHandler が含まれています。

以下も参照してください。

JSF/PrimeFaces ajax リクエストでのセッション タイムアウトと ViewExpiredException の処理

于 2014-02-18T10:37:17.000 に答える
0

ビューの有効期限を処理するには、このアプローチを試してください: プロジェクトに次の 2 つのクラスを作成します。

import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;

public class ViewExpiredExceptionExceptionHandlerFactory extends
        ExceptionHandlerFactory {

    private ExceptionHandlerFactory parent;

    public ViewExpiredExceptionExceptionHandlerFactory(
            ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return new ViewExpiredExceptionExceptionHandler(
            parent.getExceptionHandler());
    }
}

public class ViewExpiredExceptionExceptionHandler extends
        ExceptionHandlerWrapper {

    private ExceptionHandler wrapped;

    public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) {
        this.wrapped = wrapped;
    }

    @Override
    public ExceptionHandler getWrapped() {
        return this.wrapped;
    }

    @Override
    public void handle() throws FacesException {
        for (Iterator<ExceptionQueuedEvent> i = 
                getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
            ExceptionQueuedEvent event = i.next();
            ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)
                event.getSource();
            Throwable t = context.getException();
            if (t instanceof ViewExpiredException) {
                ViewExpiredException vee = (ViewExpiredException) t;
                FacesContext facesContext = FacesContext.getCurrentInstance();
                Map<String, Object> requestMap = facesContext
                    .getExternalContext().getRequestMap();
                NavigationHandler navigationHandler = facesContext
                    .getApplication().getNavigationHandler();
                try {
                    // Push some useful stuff to the request scope for use in
                    // the page
                    requestMap.put("currentViewId", vee.getViewId());
                    navigationHandler.handleNavigation(facesContext, null,
                        "/index");
                    facesContext.renderResponse();
                } finally {
                    i.remove();
                }
            }
        }
        // At this point, the queue will not contain any ViewExpiredEvents.
        // Therefore, let the parent handle them.
        getWrapped().handle();
    }
}

faces-config.xml に次の行を追加します。

<factory>
    <exception-handler-factory>path.to.class.ViewExpiredExceptionExceptionHandlerFactory</exception-handler-factory>

それだけです。準備完了です。

編集

わかりました、Omnifaces のやり方を忘れていました。エラー用のページを設定すると、404 用のページと、今は覚えていない別のページを作成するように警告されるため、これは使用しません。faces-config.xml に次を追加する必要があります。

<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>

あなたのコードは動作します。詳細については、omnifaces Web サイトhttp://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler;jsessionid=sOwX0FVqcY-InUhvDWEMksfQの FullAjaxExceptionHandlerFactory のショーケースを参照してください。

必要な jar をプロジェクトに追加することを忘れないでください。

于 2014-02-17T09:49:49.620 に答える