2014-05-23 29 views
6

'da özel bir etiket işleyicisi uygularken, aşağıdaki etiket işleyici sınıfı verildi.java.lang.IllegalStateException: java.lang.InstantiationException, JSF

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); 
      } 
     } 
    } 
} 

Etiket işleyicisi, dönüştürme başarısız olduğunda yalnızca bir sayfaya yönlendirmek içindir.

Bu, bir XHTML sayfasında aşağıdaki gibi kullanılır.

<?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> 

biz <f:metadata><ui:define name="metaData"> içine kapatılmış olduğu bir şablon var <f:viewParam> sadece Gerçekte

converter="javax.faces.Long" gibi isteğe bağlı bir dönüştürücü özelliği olabilir. Verilen <p:commandButton> basıldığında

@ManagedBean 
@RequestScoped 
public final class TestManagedBean 
{ 
    private Long id; // Getter and setter. 

    public TestManagedBean() {} 

    public void submitAction() { 
     System.out.println("submitAction() called."); 
    } 
} 

aşağıdaki istisnası atılır:

ilişkili JSF fasulye başardı.

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 

Bu etiket işleyici yalnızca <f:viewParam> ile ilişkili olmalıdır ve tamamen geri sonrası yapıldığında, örneğin içinde atlandı.

Herhangi bir çözüm var mı? Önemli


: apply() yöntemi içinde koşullu kontroller sırasında

,

verilen butonuna tıklandığında
if (parent instanceof UIViewRoot && !context.getFacesContext().isPostback()) { 
    System.out.println("Inside if"); 
    ((UIViewRoot) parent).subscribeToEvent(PostValidateEvent.class, this); 
} 

, bu durum bariz olarak false değerlendirilir. Bu nedenle, herhangi bir sorun olmamalıdır.

Şaşırtıcı bir şekilde, istisna if ifadesindeki tek satır aşağıdaki gibi kaldırıldığında istisna kaybolur.

if (parent instanceof UIViewRoot && !context.getFacesContext().isPostback()) { 
    //Debug statements only. 
} 

Bu koşul yanlış olarak değerlendirilir olsa verilen <p:commandButton> bu durumda basıldığında, yukarıda belirtildiği gibi istisna değildir.

durum :) Varsayılan olarak

cevap

9

, MTU (<input type="hidden" name="javax.faces.ViewState"> gibi) görünümünde herhangi <h:form> Görünüm durumunun (bileşen ağaç durumu) serializes bu tür görmedim. Bu, bu formdaki geri gönderme isteğinin geri yükleme görünümü sırasında geri yüklenir. JSF görünüm durumu, ağaçtaki bileşenlerin bileşen sistem olay dinleyicilerinin yanı sıra diğerlerini de kapsar.

Bu hat

((UIViewRoot) parent).subscribeToEvent(PostValidateEvent.class, this); 

UIViewRoot bileşenine birini ekler ve bu daha sonra tefrika edilmesi gerekmektedir.

4 seçeneğiniz var:

  1. o Serializable uygulamak edelim.
  2. Externalizable uygulayalım.
  3. İşini bitirdiğinde dinleyicinin aboneliğini iptal edin.
  4. ComponentSystemEventListener yerine SystemEventListener kullanın. Bu özel durumda

, sürece bireysel <f:viewParam> içindeki etiketinin iç içe desteklemek gerekmez, ama sadece <f:metadata> yılında, daha sonra seçenek 4 yeterli olacaktır olarak. ComponentSystemEventListener arabirimini SystemEventListener ile değiştirin, yalnızca UIViewRoot için true değerini döndürmek üzere isListenerForSource() yöntemini uygulayın, son olarak dinleyiciye abone olmak için UIViewRoot#subscribeToViewEvent() kullanın.

public final class ViewParamValidationFailed extends TagHandler implements SystemEventListener { 
    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).subscribeToViewEvent(PostValidateEvent.class, this); 
     } 
    } 

    @Override 
    public boolean isListenerForSource(Object source) { 
     return source instanceof UIViewRoot; 
    } 

    @Override 
    public void processEvent(SystemEvent 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); 
      } 
     } 
    } 

}