在<h:form> submit </h:form> </f:viewparam>期间未设置<f:viewparam>

时间:2013-09-16 10:06:33

标签: jsf jsf-2 primefaces cdi viewparams

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

为此,我创建了一个请求范围的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注释。如果您认为代码的其余部分(模板,转换器)具有任何相关性,我很乐意添加它们。

1 个答案:

答案 0 :(得分:2)

这是一种预期的行为。使用<f:viewParam /> you're setting the value in the bean during GET request。设置了值,这就是为什么你的页面正确呈现,但是你的bean是@RequestScoped,所以它的状态从一个请求丢失到另一个请求。当您使用p:commandButton执行POST请求时,其值实际为 null 。要解决它,您应该使用@ViewScoped bean。