在我之前的问题之后,我有一个问题,如果我在faces-config.xml中注册RedirectNavigationHandler后使用<p:button>
,为什么会抛出这个异常。:
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(ThreadPoolExecutor.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
用<p:commandButton>
可以,用<p:button>
不行。
这是我的faces-config.xml摘录:
<application>
...
<navigation-handler>id.co.sofcograha.RedirectNavigationHandler</navigation-handler>
...
</application>
和代码:
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);
}
}
maven依赖项:
<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>
对这件事有什么想法吗?对于JSF 2.0,显然应该扩展ConfigurableNavigationHandler
。
ConfigurableNavigationHandler
扩展了NavigationHandler
的契约,允许对构成导航规则库的NavigationCases
进行运行时检查。如果实现符合引入该类的规范版本(或更高版本),则必须使其NavigationHandler
成为该类的扩展。
(强调我的)这是NavigationHandler
javadoc中没有提到/警告的,所以我在你之前的问题中完全忽略了这一点。
你可以这样做:
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;
}
}
}