当前位置: 首页 > 知识库问答 >
问题:

JSF 2 基本@RequestScoped CRUD

萧心水
2023-03-14

我有这些简单的页面:

list.xhtml

<h:form id="form">  
    <h:dataTable value="#{testBean.model}" var="elem">
        <h:column>
            <f:facet name="header">code</f:facet>
            #{elem.code}
        </h:column>
        <h:column>
            <f:facet name="header">description</f:facet>
            #{elem.description}
        </h:column>
        <h:column>
            <f:facet name="header">action</f:facet>
            <h:commandButton action="#{testBean.edit(elem)}" value="edit"/>
        </h:column>
    </h:dataTable>
</h:form>

edit.xhtml

<h:form id="form">
    <h:panelGrid columns="2">
        <h:outputLabel value="code"/>
        <h:inputText value="#{testBean.selection.code}"/>

        <h:outputLabel value="description"/>
        <h:inputText value="#{testBean.selection.description}"/>
    </h:panelGrid>

    <h:commandButton action="#{testBean.update}" value="update"/>
</h:form>

这个豆子:

@ManagedBean
public class TestBean implements Serializable
{
    private static final long serialVersionUID = 1L;

    @EJB
    private PersistenceService service;
    private Object selection;
    private List<UnitType> model;

    @PostConstruct
    public void init()
    {
        model = service.findAll(UnitType.class);
    }

    public String edit(Object object)
    {
        System.out.println(Tracer.current(object));
        setSelection(object);
        return "edit";
    }

    public String update()
    {
        System.out.println(Tracer.current(selection));
        return "list";
    }

    // getters and setters
}

因此,当我单击其中一个“编辑”按钮时,它会导航到“edit.jsf”,显示已填充的输入,但当我单击“更新”按钮时会出现以下错误:

javax.el.PropertyNotFoundException: /test2/edit.xhtml @27,54 value="#{testBean.selection.code}": Target Unreachable, 'null' returned null

请注意,我知道如何实现@ViewScope接口来管理CRUD操作,但这是一个简单的概念证明,我需要更好地理解JSF生命周期。

所以我希望“testBean”是@RequestScoped

更新尝试使用f:viewParam,仍然无法理解...

list.xhtml

<?xml version="1.0" encoding="ISO-8859-1"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>test list</title>
    </h:head>

    <h:body>
        <h:messages/>

        <h:form id="form">
            <h:dataTable value="#{testBean2.model}" rows="10" var="elem">
                <h:column>
                    <f:facet name="header">converterString</f:facet>
                    #{elem.converterString}
                </h:column>
                <h:column>
                    <f:facet name="header">first name</f:facet>
                    #{elem.firstName}
                </h:column>
                <h:column>
                    <f:facet name="header">last name</f:facet>
                    #{elem.lastName}
                </h:column>
                <h:column>
                    <f:facet name="header">action</f:facet>
                    <h:commandButton action="#{testBean2.edit}" value="edit">
                        <f:param name="entity" value="#{elem.converterString}"/>
                    </h:commandButton>
                    <h:commandButton action="#{testBean2.edit2}" value="edit2">
                        <f:param name="entity" value="#{elem.converterString}"/>
                    </h:commandButton>
                </h:column>
            </h:dataTable>
        </h:form>
    </h:body>
</html>

edit.xhtml

<?xml version="1.0" encoding="ISO-8859-1"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core">
    <f:metadata>
        <f:viewParam id="entityParam" name="entity" value="#{testBean2.selection}" converter="entityConverter" required="true"/>
    </f:metadata>

    <h:head>
        <title>test edit</title>
    </h:head>

    <h:body>
        <h:messages/>

        <h:form id="form">
            <h:panelGrid columns="2">
                <h:outputLabel value="selection"/>
                <h:outputText value="#{testBean2.selection.converterString}"/>

                <h:outputLabel value="firstName"/>
                <h:inputText value="#{testBean2.selection.firstName}"/>

                <h:outputLabel value="lastName"/>
                <h:inputText value="#{testBean2.selection.lastName}"/>
            </h:panelGrid>

            <h:commandButton action="#{testBean2.update}" value="update" ajax="false">
                <f:param name="entity" value="#{testBean2.selection.converterString}"/>
            </h:commandButton>
        </h:form>
    </h:body>
</html>

testBean2.java

@ManagedBean
public class TestBean2 implements Serializable
{
    private static final long serialVersionUID = 1L;

    @EJB
    private PersistenceService service;

    private Object selection;
    private List<Person> model;

    @PostConstruct
    public void init()
    {
        Tracer.out();
        model = service.queryAll(Person.class);
    }

    public String edit()
    {
        JsfUtils.addSuccessMessage("edited");
        return "edit";
    }

    public String edit2()
    {
        JsfUtils.addSuccessMessage("edited");
        return "edit?faces-redirect=true&amp;includeViewParams=true";
    }

    public void update()
    {
        Tracer.out(selection);
        JsfUtils.addSuccessMessage("updated");
    }

    // getters and setters
}

如果我按下“编辑”按钮,它将进入<code>编辑</code>页面,但选择为空,不会显示任何消息。

如果我按下"edit2"按钮,它会转到编辑页面,但选择为空,显示所需的消息和url是edit.jsf?entity=

我到底做错了什么?

共有3个答案

邢凯歌
2023-03-14

最后我找到了一个方法:数据将在一个长的范围,在短的bean。

请注意,这只是概念证明,而不是真正的用例。并且要注意,在处理@Request estScopebean时,PrimeFaces惰性DataTable模型范围

@ManagedBean
public class TestBean
{
    @EJB
    private PersistenceService service;

    @ManagedProperty("#{viewScope.item}")
    private Item item;

    @ManagedProperty("#{sessionScope.model}")
    private EntityDataModel<Item> model;

    @PostConstruct
    public void init()
    {
        if(model == null)
        {
            model = new EntityDataModel<Item>(Item.class);
            Faces.setSessionAttribute("model", model);
        }
    }

    public String update()
    {
        Faces.getFlash().setKeepMessages(true);

        try
        {
            item = service.update(item);
            Faces.setViewAttribute("item", item);

            JsfUtils.addSuccessMessage("updated");

            return "view?faces-redirect=true&includeViewParams=true";
        }
        catch(Exception e)
        {
            e.printStackTrace();
            JsfUtils.addErrorMessage(e);
        }

        return null;
    }

    // getters and setters, other actions, ...
}

list.xhtml

<p:dataTable value="#{testBean.model}" var="elem" ...>
    ...

    <p:column exportable="false" toggleable="false" headerText="#{bundle.actions}">

        <!-- two techniques available for navigation -->

        <p:button outcome="view?id=#{elem.converterString}" icon="#{icons.view}" />

        <p:commandButton rendered="#{user.isEditAllowed(elem)}"
            action="edit?faces-redirect=true&amp;includeViewParams=true" process="@form"
            icon="#{icons.edit}">
            <f:param name="id" value="#{elem.converterString}" />
        </p:commandButton>
    </p:column>
</p:dataTable>

view.xhtml

<f:metadata>
    <o:viewParam id="itemId" name="id" value="#{viewScope.item}" required="true"
        converter="entityConverter" />
</f:metadata>

<ui:composition template="/WEB-INF/templates/template.xhtml">
    <ui:define name="content">
        <p:panelGrid columns="2">
            <h:outputLabel value="#{bundle.name}" />
            <h:outputText value="#{item.name}" />

            ...
        </p:panelGrid>

        <p:button outcome="list" value="#{bundle.list}" icon="#{icons.list}" />

        <p:button rendered="#{user.isEditAllowed(item)}" 
            outcome="edit?id=#{item.converterString}" value="#{bundle.edit}"
            icon="#{icons.edit}" />
    </ui:define>
</ui:composition>

edit.xhtml

<f:metadata>
    <o:viewParam id="itemId" name="id" value="#{viewScope.item}" required="true"
        converter="entityConverter" />
</f:metadata>

<ui:composition template="/WEB-INF/templates/template.xhtml">
    <ui:define name="content">
        <p:panelGrid columns="2">
            <h:outputLabel value="#{bundle.name}" />
            <h:panelGroup>
                <p:inputText id="name" value="#{item.name}" />
                <p:message for="name" />
            </h:panelGroup>

            ...
        </p:panelGrid>

        <p:commandButton process="@form" update="@form" action="#{testBean.update}" 
            value="#{bundle.update}" icon="#{icons.update}" />

        <p:button outcome="view?id=#{item.converterString}" value="#{bundle.cancel}" 
            icon="#{icons.cancel}" />
    </ui:define>
</ui:composition>
咸星波
2023-03-14

在我看来,没有干净的方法来实现你想要的。

我建议您只需在请求之间传递Id attr作为简单的请求参数。因此,在后构造函数中,检查参数值是否已设置,并在此基础上,查看持久层。

或者,使用您已有的设置,绑定:

<h:inputText value="#{testBean.selection.code}"/>

组件,并在必要时对其调用getValue()。不管怎样,它仍然不整洁。

如果您发现任何其他方法,请告诉我们。

弓嘉纳
2023-03-14

按照我的理解,当你的第二个请求到达testBean时,选择对象为空。如果您使用会话bean运行此命令,则可能不会出现此错误。

 类似资料:
  • 我用Eclipse创建了一个新项目 源文档:jndi:/localhost/jsf测试portlet/WEB-INF/faces-config。xml原因:Class'org。springframework。网状物jsf。埃尔。SpringBeanFacesELResolver'缺少运行时依赖项:java。lang.NoClassDefFoundError:org/springframework/

  • Glassfish 3.1.2,Mojarra 2.1.6,SSL已激活 也是一篇关于资源缓存的好文章。在我们的应用服务器中,SSL被激活。我们看到静态资源(图像、脚本、css)没有缓存。 下面是我的测试筛选器: 过期:确定。它是一个静态资源,不会改变,因此我们将到期日期设置在未来的一个月。 上次修改:不确定。我读到,将此设置为过去也会影响缓存 缓存控制:OK。允许安全缓存。安全影响? 此设置是否

  • 我使用Spring 3.2.2与Primeface 4.0和Hibernate 4.2。我在我的实体上有JSR303验证注释,并且我配置了Spring来在服务层验证它们——这很好。 但是我希望在调用服务之前启动JSF验证,但事实并非如此。我所做的所有研究都表明,我只需在类路径中添加一个验证程序,JSF2就会自动应用。 我已将建议的JAR添加到我的类路径中: 完整的依赖关系树可以在https://g

  • 问题内容: 假设我有一个管理用户的应用程序。您可以添加新用户,删除他们,编辑详细信息等。每个用户都有一个ID,并在URL上具有详细信息页面,如下所示: 现在,如果ID 123的用户不存在怎么办?我认为自然反应将是404标准错误。与您在URL中打错字(例如/user/dtail.jsf)时所输出的完全相同。所以问题是:有这种方法吗? 还是这个反应(404)合适? 谢谢。 问题答案: 只需将验证器附加

  • 我想,我的java代码是正确的,但记录并没有显示在dataTable上。 请检查下面的代码。我不知道我在哪里犯了错误。 .xhtml JAVA getResultList getResultList方法返回一个正确的值,我调试它。我认为问题在于userDataList。

  • 基差数据 接口名称 basis 接口描述 基差数据接口 请求参数 参数名 说明 举例 variety 品种编码 RB date 查询日期 2018-08-08 返回参数 参数名 类型 说明 trans_date date 查询日期 spot float 现货价格 basis float 基差,基差 = 现货价格 - 期货价格 basis_rate float 基差率,基差率 = (现货价格 - 期

  • 本文向大家介绍StackExchange.Redis 基本,包括了StackExchange.Redis 基本的使用技巧和注意事项,需要的朋友参考一下 示例 连接后,您可以通过调用ISubscriber.Publish方法来发布消息: 消费者可以使用该ISubscriber.Subscribe方法订阅频道。发布者发送的消息将由传递给此方法的处理程序处理。            

  • 本文向大家介绍C#基本,包括了C#基本的使用技巧和注意事项,需要的朋友参考一下 示例 LINQ对于查询集合(或数组)非常有利。 例如,给定下面的示例数据: 我们可以使用LINQ语法这个数据“查询”。例如,要检索今天谁吃零食的所有学生: 或者,用90或以上年级学生检索,只有回到自己的名字,而不是完整的Student对象: LINQ的功能由执行相同的功能,具有几乎相同的性能,但写的很不同的两个语法的。