使用自定义ViewHandler在登录页面上处理ViewExpiredException

时间:2012-08-21 03:26:49

标签: java jsf-2 facelets viewexpiredexception

在我的网络应用程序中,当会话过期且用户发起请求(整页或AJAX)时,用户将被重定向到登录页面,并显示会话已过期的消息。问题是,当登录页面保持打开足够长的时间以使会话过期并且用户尝试登录时,用户将被重定向到登录页面,并显示会话已过期的消息。

我遇到了this solution,但它适用于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 个答案:

答案 0 :(得分:0)

它已移至ViewDeclarationLanguage#buildView(),因为此步骤与所使用的视图技术(Facelets,JSP,JavaVDL等)分离。

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

更简单地扩展ViewHandlerWrapper。这样您就不需要那么多委托方法了。