引用我之前的question,为什么@PostConstruct方法无法运行?
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 net.bounceme.dur.nntp.Detail@c8e43a
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 net.bounceme.dur.nntp.Detail@c8e43a
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 net.bounceme.dur.nntp.Detail@c8e43a
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..
我之前获得了更好的输出,其中bean被实例化但是具有默认值并且没有及时获取URL参数,因此一些字段被填充而一些字段没有填充。
如果我的Java代码不清楚,请告诉我以什么方式不清楚。例如,我知道没有更好的方法将String解析为Integer。请参阅评论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参数作为方法参数的getter / setter方法,从而导致bean处于不确定状态。 bean已经过实例化,但字段尚未使用URL参数中的值进行初始化。这个,我无法确定是否已使用URL参数初始化bean。
以前我输出的地方比较清楚,但目前我只能生成这个错误。
出于实际目的,我刚刚离开并将@PostConstruct方法的内容移动到Detail.setId(String),这至少有效。看看oracle docs,我只是没有看到这个直接覆盖,但是我从这些文档中得出的含义是使用转换器,这也是之前建议的。
我比实际实现转换器更加好奇,因为它似乎是做一件简单事情的一种非常复杂的方式。但是,@ PostConstruct中的“逻辑”是否属于转换器?
上面的代码不是我实际使用的,只是针对这个问题,这就是“逻辑”工作的原因,而不是@PostConstruct方法,而是setId()方法。
答案 0 :(得分:3)
尝试使用@PostConstruct毫无意义,因为从我的角度来看 收集,该方法在参数之前的CDI魔法之前执行 读取。
Ooops,然后是规范must be wrong :) Mate,你的代码看起来像一团糟,你的项目设置可能也是如此?