質問

I have a JSF 2 application that retrieves data from the database and displays it on a page. I have a property get method called "getCurrentPage" which will display the database data. Inside this method if no data exists for the specified page, I want to redirect to a 404 page. I tried

FacesContext.getCurrentInstance().getExternalContext().redirect("404.xhtml");

but I get a java.lang.IllegalStateException. How to I redirect?

Here is my XHTML snippet

<h:panelGroup layout="block">
   <h:outputText escape="false" value="#{common.currentPage.cmsPageBody}"/>
</h:panelGroup>

Here is my bean snippet

public CmsPage getCurrentPage() {
    HttpServletRequest request = (HttpServletRequest) (FacesContext.getCurrentInstance().getExternalContext().getRequest()); 

    try {
        String requestUrl = (String) request.getAttribute("javax.servlet.forward.request_uri");

        if (this.currentCmsPage == null) {
        // Page not found. Default to the home page.
        this.currentCmsPage = cmsPageBL.getCmsPage("/en/index.html", websiteId);
        } else {
        this.currentCmsPage = cmsPageBL.getCmsPage(requestUrl, websiteId);
        }

        if (this.currentCmsPage == null) {
        FacesContext.getCurrentInstance().getExternalContext().redirect("404.xhtml");
        }
        }

    } catch (Exception ex) {
        log.error("getCurrentPage Exception: ", ex);
    }

    return currentCmsPage;
    }
}
役に立ちましたか?

解決

Thou should not perform business logic in getter methods. It's only recipe for trouble in all colors. Getter methods are supposed to solely return already-prepared properties. Just use a pre render view event listener instead.

E.g.

<f:event type="preRenderView" listener="#{common.initCurrentPage}" />
<h:panelGroup layout="block">
   <h:outputText escape="false" value="#{common.currentPage.cmsPageBody}"/>
</h:panelGroup>

with

public void initCurrentPage() throws IOException {
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    String requestUrl = (String) ec.getRequestMap().get(RequestDispatcher.FORWARD_REQUEST_URI);

    if (currentCmsPage == null) {
        // Page not found. Default to the home page.
        currentCmsPage = cmsPageBL.getCmsPage("/en/index.html", websiteId);
    } else {
        currentCmsPage = cmsPageBL.getCmsPage(requestUrl, websiteId);
    }

    if (currentCmsPage == null) {
        ec.redirect(ec.getRequestContextPath() + "/404.xhtml");
    }
}

public CmsPage getCurrentPage() {
    return currentCmsPage;
}

Note that I also improved some poor logic.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top