Обработка ViewExpiredException на странице входа в систему с помощью пользовательского ViewHandler

В моем веб-приложении, когда сеанс истекает и пользователь инициирует запрос (полная страница или AJAX), пользователь перенаправляется на страницу входа с сообщением об истечении сеанса. Проблема заключается в том, что когда страница входа остается открытой достаточно долго, чтобы истек срок сеанса, и пользователь пытается войти, пользователь перенаправляется на страницу входа с сообщением об истечении сеанса.

Я сталкивался с этим решением, но оно предназначено для JSF 1.x и не будет работать с JSF 2. Поэтому я начал создавать свое собственное:

public class LoginViewHandler extends ViewHandler
{
    public LoginViewHandler(ViewHandler parent)
    {
        this.parent = parent;
    }

    @Override
    public Locale calculateLocale(FacesContext context)
    {
        return parent.calculateLocale(context);
    }

    @Override
    public String calculateRenderKitId(FacesContext context)
    {
        return parent.calculateRenderKitId(context);
    }

    @Override
    public UIViewRoot createView(FacesContext context, String viewId)
    {
        return parent.createView(context, viewId);
    }

    @Override
    public String getActionURL(FacesContext context, String viewId)
    {
        return parent.getActionURL(context, viewId);
    }

    @Override
    public String getResourceURL(FacesContext context, String path)
    {
        return parent.getResourceURL(context, path);
    }

    @Override
    public void renderView(FacesContext context, UIViewRoot viewToRender)
            throws IOException, FacesException
    {
        parent.renderView(context, viewToRender);
    }

    @Override
    public UIViewRoot restoreView(FacesContext context, String viewId)
    {
        UIViewRoot viewRoot = parent.restoreView(context, viewId);

        if (viewRoot == null && viewId.equals("/login.xhtml"))
        {
            parent.initView(context);

            viewRoot = parent.createView(context, viewId);
            context.setViewRoot(viewRoot);

            try
            {
                buildView(context, viewRoot); // Compile error!
            }
            catch (IOException e)
            {
                log.log(Level.SEVERE, "Error building view", e); 
            }
        }

        return viewRoot;
    }

    @Override
    public void writeState(FacesContext context) throws IOException
    {
        parent.writeState(context);
    }

    private ViewHandler parent;
}

Тем не менее, нет метода с именем buildView, Я не уверен, что он делает, зачем это нужно и чем его заменить. Есть идеи?

1 ответ

Решение

Он был перенесен в ViewDeclarationLanguage#buildView() поскольку этот шаг не связан с используемой технологией представления (Facelets, JSP, JavaVDL и т. д.).

context.getApplication().getViewHandler()
    .getViewDeclarationLanguage(context, viewId).buildView(context, viewRoot);

Кстати проще расширить ViewHandlerWrapper вместо. Таким образом, вам не нужна эта куча методов-делегатов.

Другие вопросы по тегам