2012-04-13 15 views
-1

Verweis auf eine vorherige question von mir, warum ist die @ PostConstruct-Methode nicht ausführbar?Anwendungsfall für FacesConverter

Glasfischen gibt:

INFO: MessageBean.. 
INFO: MessageBean.getModel.. 
INFO: SingletonNNTP.getMessages.. 
INFO: MessageBean.getModel.. 
INFO: SingletonNNTP.getMessages.. 
INFO: SingletonNNTP.setIndex..2,205 
INFO: SingletonNNTP.setIndex..2,205 
INFO: SingletonNNTP.setIndex..2,206 
INFO: SingletonNNTP.setIndex..2,206 
INFO: SingletonNNTP.setIndex..2,207 
INFO: SingletonNNTP.setIndex..2,207 
INFO: SingletonNNTP.setIndex..2,208 
INFO: SingletonNNTP.setIndex..2,208 
INFO: SingletonNNTP.setIndex..2,209 
INFO: SingletonNNTP.setIndex..2,209 
INFO: SingletonNNTP.setIndex..2,210 
INFO: SingletonNNTP.setIndex..2,210 
INFO: SingletonNNTP.setIndex..2,211 
INFO: SingletonNNTP.setIndex..2,211 
INFO: SingletonNNTP.setIndex..2,212 
INFO: SingletonNNTP.setIndex..2,212 
INFO: SingletonNNTP.setIndex..2,213 
INFO: SingletonNNTP.setIndex..2,213 
INFO: SingletonNNTP.setIndex..2,214 
INFO: SingletonNNTP.setIndex..2,214 
INFO: SingletonNNTP.setIndex..2,215 
INFO: SingletonNNTP.setIndex..2,215 
INFO: MessageBean.getModel.. 
INFO: SingletonNNTP.getMessages.. 
INFO: Detail.. 
WARNING: /foo/detail.xhtml @9,67 value="#{detail.id}": org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public net.bounceme.dur.nntp.Detail.configBean() on [email protected] 
javax.el.ELException: /foo/detail.xhtml @9,67 value="#{detail.id}": org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public net.bounceme.dur.nntp.Detail.configBean() on [email protected] 
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114) 
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194) 
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182) 
    at javax.faces.component.UIOutput.getValue(UIOutput.java:169) 
    at javax.faces.component.UIInput.validate(UIInput.java:972) 
    at javax.faces.component.UIInput.executeValidate(UIInput.java:1233) 
    at javax.faces.component.UIInput.processValidators(UIInput.java:698) 
    at javax.faces.component.UIViewParameter.processValidators(UIViewParameter.java:273) 
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) 
    at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) 
    at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172) 
    at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1542) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:849) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:746) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1045) 
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:228) 
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
    at java.lang.Thread.run(Thread.java:722) 
Caused by: org.jboss.weld.exceptions.WeldException: WELD-000049 Unable to invoke [method] @PostConstruct public net.bounceme.dur.nntp.Detail.configBean() on [email protected] 
    at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:508) 
    at org.jboss.weld.bean.ManagedBean$ManagedBeanInjectionTarget.postConstruct(ManagedBean.java:174) 
    at org.jboss.weld.bean.ManagedBean.create(ManagedBean.java:291) 
    at org.jboss.weld.context.AbstractContext.get(AbstractContext.java:107) 
    at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:90) 
    at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:79) 
    at net.bounceme.dur.nntp.Detail$Proxy$_$$_WeldClientProxy.getId(Detail$Proxy$_$$_WeldClientProxy.java) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:363) 
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176) 
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203) 
    at com.sun.el.parser.AstValue.getValue(AstValue.java:138) 
    at com.sun.el.parser.AstValue.getValue(AstValue.java:183) 
    at com.sun.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:224) 
    at org.jboss.weld.el.WeldValueExpression.getValue(WeldValueExpression.java:50) 
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109) 
    ... 38 more 
Caused by: java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:601) 
    at org.jboss.weld.util.reflection.SecureReflections$13.work(SecureReflections.java:264) 
    at org.jboss.weld.util.reflection.SecureReflectionAccess.run(SecureReflectionAccess.java:52) 
    at org.jboss.weld.util.reflection.SecureReflectionAccess.runAsInvocation(SecureReflectionAccess.java:137) 
    at org.jboss.weld.util.reflection.SecureReflections.invoke(SecureReflections.java:260) 
    at org.jboss.weld.introspector.jlr.WeldMethodImpl.invoke(WeldMethodImpl.java:174) 
    at org.jboss.weld.bean.AbstractClassBean.defaultPostConstruct(AbstractClassBean.java:506) 
    ... 56 more 
Caused by: java.lang.NumberFormatException: null 
    at java.lang.Integer.parseInt(Integer.java:454) 
    at java.lang.Integer.parseInt(Integer.java:527) 
    at net.bounceme.dur.nntp.Detail.configBean(Detail.java:29) 
    ... 66 more 

INFO: Detail.. 

Ich war besser früher ausgegeben bekommen, in dem die Bohne instanziiert wurde aber mit Standardwerten und nicht die URL-Parameter in der Zeit bekommen, so dass einige Felder ausgefüllt wurden und einige nicht.

Wenn mein Java-Code unklar ist, lassen Sie mich bitte wissen, in welcher Weise es unklar ist. Ich kenne keine bessere Möglichkeit, beispielsweise String zu Integer zu analysieren. Siehe Kommentare here.

package net.bounceme.dur.nntp; 

import java.io.Serializable; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.annotation.PostConstruct; 
import javax.enterprise.context.ConversationScoped; 
import javax.inject.Named; 
import javax.mail.Message; 

@Named 
@ConversationScoped 
public class Detail implements Serializable { 

    private static final long serialVersionUID = 1L; 
    private static final Logger LOG = Logger.getLogger(Detail.class.getName()); 
    private String id = null; 
    private Message message = null; 
    private SingletonNNTP nntp = SingletonNNTP.INSTANCE; 
    private int forward = 0; 
    private int back = 0; 

    public Detail() { 
     LOG.info("Detail.."); 
    } 

    @PostConstruct 
    public void configBean() { 
     int intId = Integer.parseInt(id); 
     try { 
      nntp.setIndex(intId); 
      message = nntp.getMessage(); 
     } catch (Exception ex) { 
      LOG.info("Detail.configBean..failed to set message"); 
     } 
     setForward(intId + 1); 
     setBack(intId - 1); 
    } 

    public Message getMessage() throws Exception { 
     LOG.info("Detail.getMessage.." + getId()); 
     return message; 
    } 

    public void setMessage(Message message) { 
     LOG.info("Detail.setMessage.."); 
     this.message = message; 
    } 

    public String getId() throws Exception { 
     LOG.info("Detail.getId.." + id); 
     if (id == null) { //should never be null, should get from URL as param 
      LOG.info("..setting default id"); 
      id = String.valueOf(2000); 
     } 
     return id; 
    } 

    public void setId(String id) throws Exception { 
     LOG.info("Detail.setId.." + id); 
     this.id = id; 
    } 

    public int getForward() throws Exception { 
     LOG.info("Detail.getForward.." + forward); 
     return forward; 
    } 

    public void setForward(int forward) { 
     LOG.info("Detail.setForward.." + forward); 
     this.forward = forward; 
    } 

    public int getBack() throws Exception { 
     LOG.info("Detail.setBack.." + back); 
     return back; 
    } 

    public void setBack(int back) { 
     LOG.info("Detail.setBack.." + back); 
     this.back = back; 
    } 
} 

und die Ansicht:

<?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:ui="http://java.sun.com/jsf/facelets" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:h="http://java.sun.com/jsf/html"> 
    <body> 
     <f:metadata> 
      <f:viewParam name="id" id="id" value="#{detail.id}" /> 
     </f:metadata> 
     <ui:composition template="./complexTemplate.xhtml"> 
      <ui:define name="top"> 
       <div style="float: left"> 
        <h:link value="back" outcome="detail" includeViewParams="true"> 
         <f:param name="id" value="#{detail.back}"/> 
        </h:link> 
       </div> 
       <div style="float: right"> 
        <h:link value="forward" outcome="detail" includeViewParams="true"> 
         <f:param name="id" value="#{detail.forward}"/> 
        </h:link> 
       </div> 
       <p align="center"><h:outputText value="#{detail.message.messageNumber}" /></p> 
      </ui:define> 
      <ui:define name="left"> 
       <h:outputText value="#{detail.message.sentDate}" /><p/> 
       <h:outputText value="#{detail.message.subject}"/><p/> 
      </ui:define> 
      <ui:define name="right"> 
      </ui:define> 
      <ui:define name="content"> 
       <h:outputText value="#{detail.message.content}" escape="false"/> 
      </ui:define> 
      <ui:define name="bottom"> 
      </ui:define> 
     </ui:composition> 
    </body> 
</html> 

Mein nehmen dazu ist, dass der Getter/setter Verfahren, die als Verfahren URL Parameter nehmen Argumente in einer Bean aufgerufen werden in einen unbestimmten Zustand nach @PostConstruct führt. Die Bean wurde instanziiert, aber die Felder wurden nicht mit Werten aus den URL-Parametern initialisiert. Dies gibt mir keine Möglichkeit zu bestimmen, ob die Bean mit URL-Parametern initialisiert wurde oder nicht.

Zuvor hatte ich ausgegeben, wo dies klarer war, aber im Moment kann ich nur diesen Fehler erzeugen.

Aus praktischen Gründen habe ich einfach den Inhalt der @ PostConstruct-Methode in die Detail.setId (String) verschoben, die zumindest funktioniert. Mit Blick auf das Orakel docs, ich sehe es nicht direkt abgedeckt, aber die Implikation, die ich aus diesen Dokumenten ziehe, ist die Verwendung eines Konverters, der auch zuvor vorgeschlagen wurde.

Ich bin eher neugierig als wahrscheinlich, einen Konverter tatsächlich zu implementieren, wie es nur scheint, eine ziemlich komplexe Art, eine einfache Sache zu tun. Die "Logik" in @PostConstruct gehört jedoch zu Recht in einen Konverter?

Der obige Code ist nicht was ich eigentlich benutze, es ist nur für diese Frage, weshalb die "Logik" funktioniert, nicht in der @ PostConstruct-Methode, sondern stattdessen die setId() -Methode.

+2

Schade, dass Sie nicht die Zeit gefunden haben, einige der Refactorings zu tun, die ich vorgeschlagen habe [hier] (http://stackoverflow.com/a/10125532/512155). Ihr Code macht es für jeden, der bereit ist zu antworten, unnötig schwer. –

+2

Versuchen Sie eine _concrete_ Programmierfrage zu stellen, ohne zu viel im Dunkeln zu tasten. Es ist schwer, deinen Gedanken zu folgen. Viele von ihnen scheinen Trugschlüsse zu sein. –

Antwort

3

Der Versuch @PostConstruct war sinnlos zu verwenden, weil von dem, was ich sammeln , dass Verfahren vor dem CDI Magie führt, wo die params gelesen werden.

Ooops, dann die Spezifikation must be wrong :) Mate, sieht der Code wie ein Durcheinander und das gleiche könnte für Ihr Projekt-Setup wahr sein?