JSF2:从支持bean导航到外部URL

JSF2:从支持bean导航到外部URL,url,redirect,jsf-2,external,logout,Url,Redirect,Jsf 2,External,Logout,这是问题的延伸 我需要在backingbean方法中使会话无效,然后转发到外部URL。在这种情况下,outputLink组件不能调用bean的操作方法logout方法。 如果使用commandLink,则会调用操作方法,但在会话无效后,会在转发到外部URL之前创建另一个会话 更具体地说:我有一个在主页上加载项目列表的视图。主页上有一组链接,其中一个是顶部的注销图像/按钮,来自模板xhtml。在模板xhtml文件中,我有调用LogoutBean.java的注销方法的commandLink代码。该

这是问题的延伸

我需要在backingbean方法中使会话无效,然后转发到外部URL。在这种情况下,outputLink组件不能调用bean的操作方法logout方法。 如果使用commandLink,则会调用操作方法,但在会话无效后,会在转发到外部URL之前创建另一个会话

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

代码:

template.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>
这是由错误引起的,行为已完全指定

基本上,你想杀死那个事件。我从来没有在这个构造中尝试过,所以我无法从经验中判断它是否有效,但您可以尝试获取事件,然后在重定向之前清除它

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

这在理论上应该是可行的。

我想,您是想在实际清除会话和重定向之前,将此代码放到LogoutBean.java中。我这样做了,看起来像是viewRoot.getViewListenersForEventClassPreRenderViewEvent.class返回null,因此导致NPE。我在视图上使用preRenderView事件的唯一原因是,我必须基于参数在支持SessionScoped bean中运行特定的操作方法。如果有其他方法可以做到这一点,我可以去掉导致此问题的preRenderView
@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");
    }
} 
@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();
    }
}
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
viewRoot.getViewListenersForEventClass(PreRenderViewEvent.class).clear();
// ...