Given the following tag handler class.
public final class ViewParamValidationFailed extends TagHandler implements ComponentSystemEventListener { private final String redirect; public ViewParamValidationFailed(TagConfig config) { super(config); redirect = getRequiredAttribute("redirect").getValue(); } @Override public void apply(FaceletContext context, UIComponent parent) throws IOException { if (parent instanceof UIViewRoot && !context.getFacesContext().isPostback()) { ((UIViewRoot) parent).subscribeToEvent(PostValidateEvent.class, this); } } @Override public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { FacesContext context = FacesContext.getCurrentInstance(); if (context.isValidationFailed()) { try { ExternalContext externalContext = context.getExternalContext(); externalContext.redirect(externalContext.getRequestContextPath() + redirect); } catch (IOException e) { throw new AbortProcessingException(e); } } } }
The tag handler is intended only to redirect to the page if the conversion fails.
This is used on XHTML pages as follows.
<?xml version='1.0' encoding='UTF-8' ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:my="http://example.com/ui" xmlns:f="http://xmlns.jcp.org/jsf/core"> <h:head> <title>Test</title> </h:head> <h:body> <f:metadata> <f:viewParam name="id" required="true" value="#{testManagedBean.id}"/> <my:viewParamValidationFailed redirect="/public_resources/PageNotFound.jsf"/> </f:metadata> <h:form id="form" prependId="true"> <p:commandButton value="Submit" actionListener="#{testManagedBean.submitAction}"/> </h:form> </h:body> </html>
we can have an optional converter attribute with <f:viewParam> , like converter="javax.faces.Long"
In fact, there is a template in which <f:metadata> enclosed in <ui:define name="metaData"> .
JSF related bean:
@ManagedBean @RequestScoped public final class TestManagedBean { private Long id;
When this <p:commandButton> , the following exception is thrown.
SEVERE: java.lang.IllegalStateException: java.lang.InstantiationException: tags.ViewParamValidationFailed at javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:153) at javax.faces.component.UIComponent$ComponentSystemEventListenerAdapter.restoreState(UIComponent.java:2633) at javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:165) at javax.faces.component.UIComponentBase.restoreAttachedState(UIComponentBase.java:1793) at javax.faces.component.UIComponentBase.restoreSystemEventListeners(UIComponentBase.java:1911) at javax.faces.component.UIComponentBase.restoreState(UIComponentBase.java:1607) at javax.faces.component.UIViewRoot.restoreState(UIViewRoot.java:1771) at com.sun.faces.application.view.FaceletPartialStateManagementStrategy$2.visit(FaceletPartialStateManagementStrategy.java:380) at com.sun.faces.component.visit.FullVisitContext.invokeVisitCallback(FullVisitContext.java:151) at javax.faces.component.UIComponent.visitTree(UIComponent.java:1690) at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.restoreView(FaceletPartialStateManagementStrategy.java:367) at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:138) at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123) at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:590) at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:150) at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:353) at org.omnifaces.viewhandler.RestorableViewHandler.restoreView(RestorableViewHandler.java:66) at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:353) at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:197) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:121) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646) at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1682) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:344) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:70) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:316) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:160) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:734) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:673) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:99) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:174) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:357) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:260) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:188) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:191) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:168) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:189) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:838) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:564) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:544) at java.lang.Thread.run(Thread.java:722) Caused by: java.lang.InstantiationException: tags.ViewParamValidationFailed at java.lang.Class.newInstance0(Class.java:357) at java.lang.Class.newInstance(Class.java:325) at javax.faces.component.StateHolderSaver.restore(StateHolderSaver.java:150) ... 54 more
This tag handler should only be associated with <f:viewParam> and should be skipped completely when, for example, feedback is created.
Is there any solution?
Decisive:
In conditional check inside apply() method
if (parent instanceof UIViewRoot && !context.getFacesContext().isPostback()) { System.out.println("Inside if"); ((UIViewRoot) parent).subscribeToEvent(PostValidateEvent.class, this); }
When this button is pressed, this condition is evaluated as false as obvious. Therefore, there should be no problems.
Surprisingly, the exception disappears when the only line inside the if is deleted, as shown below.
if (parent instanceof UIViewRoot && !context.getFacesContext().isPostback()) {
It does not throw an exception, as indicated above, when the given <p:commandButton> pressed, although in this case the condition evaluates to false.
I have never seen such a situation :)