开发者

Custom NavigationHandler cannot be cast to javax.faces.application.ConfigurableNavigationHandler

开发者 https://www.devze.com 2023-02-25 10:38 出处:网络
Following my previous question, i have a question about why is it this exception is being thrown if i use <p:button> from primefaces after registering the RedirectNavigationHandler in the faces-

Following my previous question, i have a question about why is it this exception is being thrown if i use <p:button> from primefaces after registering the RedirectNavigationHandler in the faces-config.xml. :

SEVERE: Error Rendering View[/TBrowse.xhtml]
java.lang.ClassCastException: my.package.RedirectNavigationHandler cannot be cast to javax.faces.application.ConfigurableNavigationHandler
        at org.primefaces.component.button.ButtonRenderer.findNavigationCase(ButtonRenderer.java:114)
        at org.primefaces.component.button.ButtonRenderer.buildOnclick(ButtonRenderer.java:90)
        at org.primefaces.component.button.ButtonRenderer.encodeMarkup(ButtonRenderer.java:56)
        at org.primefaces.component.button.ButtonRenderer.encodeEnd(ButtonRenderer.java:38)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
        at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:853)
        at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
        at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
        at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:853)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1652)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
        at org.primefaces.component.tabview.TabViewRenderer.encodeContents(TabViewRenderer.java:177)
        at org.primefaces.component.tabview.TabViewRenderer.encodeMarkup(TabViewRenderer.java:120)
        at org.primefaces.component.tabview.TabViewRenderer.encodeEnd(TabViewRenderer.java:61)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
        at org.primefaces.renderkit.CoreRenderer.renderChild(CoreRenderer.java:59)
        at org.primefaces.renderkit.CoreRenderer.renderChildren(CoreRenderer.java:43)
        at org.primefaces.component.panel.PanelRenderer.encodeContent(PanelRenderer.java:229)
        at org.primefaces.component.panel.PanelRenderer.encodeMarkup(PanelRenderer.java:152)
        at org.primefaces.component.panel.PanelRenderer.encodeEnd(PanelRenderer.java:75)
        at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:883)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1659)
        at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
        at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:853)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1652)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
        at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1655)
        at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:399)
        at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
        at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
        at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
        at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPool开发者_StackOverflowExecutor.java:908)
        at java.lang.Thread.run(Thread.java:662)
unhandled exception : java.lang.ClassCastException: my.package.RedirectNavigationHandler cannot be cast to javax.faces.application.ConfigurableNavigationHandler
cause exception : java.lang.ClassCastException: my.package.RedirectNavigationHandler cannot be cast to javax.faces.application.ConfigurableNavigationHandler, cause exception is BE : false

Using <p:commandButton> is fine, but not so with <p:button>.

Here's my faces-config.xml excerpt :

<application>
   ...
   <navigation-handler>id.co.sofcograha.RedirectNavigationHandler</navigation-handler>
   ...
</application>

And the code :

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;

public class RedirectNavigationHandler extends NavigationHandler {
    private NavigationHandler parent;

    public RedirectNavigationHandler(NavigationHandler parent) {
        this.parent = parent;
    }

    @Override
    public void handleNavigation(FacesContext context, String from, String outcome) {
        if (outcome != null && !outcome.trim().equals("") && !outcome.endsWith("?faces-redirect=true")) {
            System.out.println("adding faces redirect for " + outcome);
            outcome += "?faces-redirect=true";
        }

        parent.handleNavigation(context, from, outcome);        
    }
}

Here's the maven dependencies :

<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-api</artifactId>
    <version>2.0.4-b09</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>com.sun.faces</groupId>
    <artifactId>jsf-impl</artifactId>
    <version>2.0.4-b09</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.primefaces</groupId>
    <artifactId>primefaces</artifactId>
    <version>2.2.1</version>
</dependency>

Any ideas on this matter ?

Thank you !


For JSF 2.0 you're apparently supposed to extend ConfigurableNavigationHandler instead.

ConfigurableNavigationHandler extends the contract of NavigationHandler to allow runtime inspection of the NavigationCases that make up the rule-base for navigation. An implementation compliant with the version of the specification in which this class was introduced (or a later version) must make it so that its NavigationHandler is an extension of this class.

(emphasis mine) This is by the way not mentioned/warned in NavigationHandler javadoc, so I completely overlooked that bit in your previous question.

Here's how you could do it:

package com.example;

import java.util.Map;
import java.util.Set;

import javax.faces.application.ConfigurableNavigationHandler;
import javax.faces.application.NavigationCase;
import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;

public class RedirectNavigationHandler extends ConfigurableNavigationHandler {

    private NavigationHandler parent;

    public RedirectNavigationHandler(NavigationHandler parent) {
        this.parent = parent;
    }

    @Override
    public void handleNavigation(FacesContext context, String from, String outcome) {
        if (!outcome.endsWith("?faces-redirect=true")) {
            outcome += "?faces-redirect=true";
        }

        parent.handleNavigation(context, from, outcome);        
    }

    @Override
    public NavigationCase getNavigationCase(FacesContext context, String fromAction, String outcome) {
        if (parent instanceof ConfigurableNavigationHandler) {
            return ((ConfigurableNavigationHandler) parent).getNavigationCase(context, fromAction, outcome);
        } else {
            return null;
        }
    }

    @Override
    public Map<String, Set<NavigationCase>> getNavigationCases() {
        if (parent instanceof ConfigurableNavigationHandler) {
            return ((ConfigurableNavigationHandler) parent).getNavigationCases();
        } else {
            return null;
        }
    }

}
0

精彩评论

暂无评论...
验证码 换一张
取 消