Jsf <;f:viewParam>;在<;h:表格>;提交

Jsf <;f:viewParam>;在<;h:表格>;提交,jsf,jsf-2,primefaces,cdi,viewparams,Jsf,Jsf 2,Primefaces,Cdi,Viewparams,我想创建一个表单来简单地修改一些项目实体的字段 为此,我创建了一个请求范围的bean和一个视图,该视图与转换器一起使用,告诉bean正在编辑哪个实体 Bean @Named @RequestScoped public class Bean { private Project selectedProject; public void setSelectedProject(Project project) { selectedProject= project;

我想创建一个表单来简单地修改一些项目实体的字段

为此,我创建了一个请求范围的bean和一个视图,该视图与转换器一起使用,告诉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>
在调试这个问题时,我发现确实调用了转换器,但是在上述生命周期发生之前,返回的项目没有在bean上设置。如果我在bean中返回一个虚拟项目,那么一切都正常,所选项目最终被设置,我可以用更新的值持久化

这是预期的行为吗?我可以在不返回虚拟项目的情况下运行此程序吗


我见过使用视图范围bean的方法。因为我们使用的是CDI,所以我更倾向于使用javax.enterprise注释。如果您认为其余代码(模板、转换器)有任何相关性,我很乐意添加它们。

这是一种预期行为。使用
。值被设置,这就是页面被正确呈现的原因,但是bean是
@requestscope
,因此它的状态从一个请求丢失到另一个请求。当您使用
p:commandButton
执行POST请求时,其值实际上是null。要解决这个问题,您应该使用
@ViewScoped
bean。

谢谢您的回答
@ViewScoped
似乎是一种选择,除非您处于基于CDI的环境中。我发现了这篇博客文章和这个答案,它揭示了如何通过
@ConversationScoped
bean实现同样的效果。不客气。这不是唯一的方法,但在纯JSF2.x中,这无疑是正确的方法。
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]