我想创建一个表单来简单地修改某些项目实体的字段。
为此,我创建了一个请求范围的 bean 和一个视图,它与转换器一起使用来告诉 bean 正在编辑哪个实体。
豆
@Named
@RequestScoped
public class Bean {
private Project selectedProject;
public void setSelectedProject(Project project) {
selectedProject= project;
}
public Project getSelectedProject() {
return selectedProject;
}
public String save() {
// Persist selectedProject...
return null;
}
}
看法
<ui:composition template="/templates/layout.xhtml"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<ui:define name="metadata">
<f:metadata>
<f:viewParam id="projectParam" name="project"
value="#{bean.selectedProject}" converter="#{projectConverter}" />
</f:metadata>
</ui:define>
<ui:define name="content">
<h:form id="projectForm">
<p:panel header="Project details">
<h:panelGrid columns="2">
<p:outputLabel for="title" value="Title" />
<h:inputText id="title" value="#{bean.selectedProject.title}" />
<p:outputLabel for="desc" value="Description" />
<h:inputTextarea id="desc" value="#{bean.selectedProject.description}" />
</h:panelGrid>
<p:commandButton id="submitButton" type="submit"
value="Save" action="#{bean.save}">
<f:param name="project" value="#{bean.selectedProject.id}" />
</p:commandButton>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
加载视图最初工作正常,加载选定的项目,表单字段填充项目的属性。但是,在保存表单时,我收到以下堆栈跟踪:
11:00:58,837 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (http--0.0.0.0-8080-3) /user/project.xhtml @42,70 value="#{bean.selectedProject.title}": Target Unreachable, 'selectedProject' returned null: javax.el.PropertyNotFoundException: /user/project.xhtml @42,70 value="#{bean.selectedProject.title}": Target Unreachable, 'selectedProject' returned null
at com.sun.faces.facelets.el.TagValueExpression.getType(TagValueExpression.java:100) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getConvertedValue(HtmlBasicInputRenderer.java:95) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1030) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIInput.validate(UIInput.java:960) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIInput.executeValidate(UIInput.java:1233) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIInput.processValidators(UIInput.java:698) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.primefaces.component.panel.Panel.processValidators(Panel.java:297) [primefaces-3.5.jar:]
at javax.faces.component.UIForm.processValidators(UIForm.java:253) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.primefaces.component.layout.Layout.processValidators(Layout.java:246) [primefaces-3.5.jar:]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1214) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1172) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) [jsf-impl-2.1.7-jbossorg-2.jar:]
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) [jsf-impl-2.1.7-jbossorg-2.jar:]
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) [jboss-jsf-api_2.1_spec-2.0.1.Final.jar:2.0.1.Final]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:329) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
at org.jboss.weld.servlet.ConversationPropagationFilter.doFilter(ConversationPropagationFilter.java:62) [weld-core-1.1.5.AS71.Final.jar:2012-02-10 15:31]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:280) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:248) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:275) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:489) [jbossweb-7.0.13.Final.jar:]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:153) [jboss-as-web-7.1.1.Final.jar:7.1.1.Final]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) [jbossweb-7.0.13.Final.jar:]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:368) [jbossweb-7.0.13.Final.jar:]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:877) [jbossweb-7.0.13.Final.jar:]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:671) [jbossweb-7.0.13.Final.jar:]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:930) [jbossweb-7.0.13.Final.jar:]
at java.lang.Thread.run(Thread.java:680) [classes.jar:1.6.0_51]
在调试问题的时候发现确实调用了转换器,但是在上述生命周期发生之前,返回的项目并没有设置在bean上。如果我在 bean 中返回一个虚拟项目,一切正常,最终设置选定的项目我可以使用更新的值进行持久化。
这是预期的行为吗?我可以在不返回虚拟项目的情况下运行它吗?
我见过使用视图范围 bean 的方法。由于我们使用的是 CDI,我更愿意坚持使用 javax.enterprise 注释。如果您认为其余代码(模板、转换器)有任何相关性,我很乐意添加它们。