【问题标题】:JSF 2: Navigate to external URL from a backing beanJSF 2:从支持 bean 导航到外部 URL
【发布时间】:2012-01-26 21:34:48
【问题描述】:

这是对问题的一种扩展 Navigate to external URL from a backing bean?

我需要在支持 bean 方法中使会话无效,然后转发到外部 URL。 outputLink 组件不具备调用操作方法(在本例中为 bean 的注销方法)的能力。 如果我使用 commandLink,则会调用操作方法,但在会话无效后,会在转发到外部 URL 之前创建另一个会话。

更具体地说:我有一个在主页上加载项目列表的视图。主页顶部有一堆来自模板 xhtml 的链接(其中一个是注销图像/按钮)。在模板 xhtml 文件中,我有调用 LogoutBean.java 的注销方法的 commandLink 代码。该方法按预期正常调用,但是当我在 HomeBean 的 PostConstruct 方法中放置一个断点时,我看到该方法在会话无效后被调用,然后它转发到外部 URL。如何预防?

代码:

模板.xhtml:

                        <h:form>
                        <p:panel id="HomeHeaderPanel"  styleClass="tableheaderfont" style="width:98%">
                            <h:panelGrid id="filterGrid" columns="2" cellpadding="0" styleClass="normalfont" style="width: 98%" columnClasses="leftalign,rightalign">
                                <h:panelGroup>
                                    <h:link outcome="reviewHome.xhtml?faces-redirect=true" id="homeLink"
                                        title="Review Home">
                                        <h:graphicImage value="images/home_small.png" id="homeIcon" alt="Review Home"/>
                                    </h:link>
                                    <p:spacer width="5"/>

                                    <h:commandLink action="#{logoutBean.logout}" >  
                                        <h:graphicImage value="images/logout_small.png" id="logoutIcon" alt="Logout" title="Logout"/>
                                    </h:commandLink>  

                                </h:panelGroup>
                            </h:panelGrid>
                        </p:panel>
                    </h:form>

reviewHome.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.prime.com.tr/ui">
<f:view contentType="text/html">
<ui:composition template="template.xhtml">
    <ui:define name="content">  
              <h:form styleClass="form" id="ptpReviewForm">

    <f:event listener="#{homeBean.refresh}" type="preRenderView" />...content here...
</h:form>
</ui:define>
    </ui:composition>
    </f:view>
    </html>

HomeBean.java:

@ManagedBean
@SessionScoped
public class HomeBean implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 3303546811067129792L;
public HomeBean(){}

@EJB
private ReviewEJB reviewEJB;
private List<HomeObject> homeList;


@SuppressWarnings("unused")
@PostConstruct
private void populateItpList()
{
    logger.debug("In the PostConstruct method");
    homeList = reviewEJB.getList();

}

//This method is loaded every time the Review Home view loads (prerenderView event)
public void refresh()
{
    String refresh = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("refresh");
    if(null != refresh && refresh.equalsIgnoreCase("true"))
    {
        homeList = reviewEJB.getList("another");
    }
} 

LogoutBean.java:

@ManagedBean
@SessionScoped
public class LogoutBean {


public void logout() throws ServletException
{

    try {
        ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
        ((HttpServletRequest) ec.getRequest()).logout();
        HttpSession session = (HttpSession) ec.getSession(false);

        // invalidate session
        if (session != null) {
            session.invalidate();
        }
        ec.redirect("/anotherWebAppContext/forward.jsp?link=review");

    }  catch (IOException e) {
        e.printStackTrace();
    }
}

【问题讨论】:

    标签: url redirect jsf-2 external logout


    【解决方案1】:

    这是由&lt;f:event type="preRenderView"&gt; 引起的,行为已完全指定。

    基本上你想杀死那个事件。我从未在此构造中尝试过,因此我无法根据经验判断它是否有效,但您可以尝试通过 UIViewRoot#getViewListenersForEventClass() 获取事件,然后在重定向之前将其清除。

    UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
    viewRoot.getViewListenersForEventClass(PreRenderViewEvent.class).clear();
    // ...
    

    理论上应该可行。

    【讨论】:

    • 我假设,您的意思是在实际清除会话和重定向之前将此代码放在 LogoutBean.java 中。我做了,看起来 viewRoot.getViewListenersForEventClass(PreRenderViewEvent.class) 返回 null 并因此导致 NPE
    • 我在视图上使用 preRenderView 事件的唯一原因是我必须根据参数在支持 SessionScoped bean 中运行特定的操作方法。如果有其他方法可以做到这一点,我可以摆脱导致此问题的 preRenderView
    猜你喜欢
    • 2011-03-18
    • 2011-10-21
    • 2014-01-14
    • 2011-06-29
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多