2012-04-13 75 views
-1

引用我的以前的question,爲什麼@PostConstruct方法不能運行?FacesConverter使用案例

GlassFish中給出了:

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

我得到更好的輸出更早,其中豆被實例化,但使用默認值,並沒有及時得到URL參數,使某些字段進行填充,有些不是。

如果我的Java代碼不清楚,請告訴我它不清楚什麼方式。例如,我知道沒有更好的方法將字符串解析爲整數。見評論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; 
    } 
} 

和視圖:

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

我在此採取的是,如方法參數被@PostConstruct導致豆處於不確定狀態後調用其取URL參數吸氣/ setter方法。這個bean已經被實例化,但是這些字段沒有使用URL參數中的值進行初始化。這個,我沒有辦法知道bean是否被初始化或者沒有使用URL參數。

此前我輸出的地方更清晰,但目前我只能產生這個錯誤。

出於實際的目的,我剛剛將@PostConstruct方法的內容移至了至少可以工作的Detail.setId(String)。看看oracle docs,我只是沒有看到這個直接覆蓋,但我從這些文檔中得出的含義是使用一個Converter,這也是以前的建議。

我比實際實現Converter更加好奇,因爲它似乎是一個非常複雜的簡單事情。然而,@PostConstruct中的「邏輯」正確地屬於一個轉換器?

上面的代碼不是我實際使用的,它只是針對這個問題,這就是爲什麼「邏輯」起作用,而不是在@PostConstruct方法中,而是使用setId()方法。

+2

可惜,你似乎沒有找到時間來做一些重構我建議[這裏](http://stackoverflow.com/a/10125532/512155)。你的代碼使得任何願意回答的人都不需要很難。 – 2012-04-13 08:37:04

+2

嘗試提出一個_concrete_編程問題,而不要在黑暗中摸索。很難跟隨你的想法。其中許多似乎是謬論。 – 2012-04-13 08:44:29

回答

3

嘗試使用@PostConstruct是毫無意義的,因爲,從我 聚集,其中PARAMS是 讀取方法執行之前的CDI魔力。

Ooops,然後規格must be wrong :)配合,你的代碼看起來像一團糟,同樣可能是你的項目設置?