【问题标题】:JSF throws class does not have the property for DynamicEntityJSF throws 类没有 DynamicEntity 的属性
【发布时间】:2013-12-10 16:29:15
【问题描述】:

我想使用 DynamicEntity 作为托管 bean,为我的 xhtml 表单提供属性。

当我将上述内容用作我的 xhtml 页面的支持 bean 时,出现以下异常:

The class 'com.invoice.Invoic' does not have the property 'sellerAddress'.
com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:111)
javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
javax.faces.component.UIOutput.getValue(UIOutput.java:169)
com.sun.faces.renderkit.html_basic.HtmlBasicInputRenderer.getValue(HtmlBasicInputRenderer.java:205)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.getCurrentValue(HtmlBasicRenderer.java:355)
com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeEnd(HtmlBasicRenderer.java:164)
javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1786)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
javax.faces.component.UIComponent.encodeAll(UIComponent.java:1782)
com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:402)
com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:125)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
org.ocpsoft.rewrite.faces.RewriteViewHandler.renderView(RewriteViewHandler.java:186)
javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:200)
com.tsystems.odx.idm.authentication.web.AuthenticationFilter.doFilter(AuthenticationFilter.java:231)
org.ocpsoft.rewrite.servlet.impl.HttpRewriteResultHandler.handleResult(HttpRewriteResultHandler.java:38)
org.ocpsoft.rewrite.servlet.RewriteFilter.rewrite(RewriteFilter.java:263)
org.ocpsoft.rewrite.servlet.RewriteFilter.doFilter(RewriteFilter.java:188)
com.tsystems.odx.idm.authentication.web.AuthenticationFilter.doFilter(AuthenticationFilter

我放了一个调试断点并查看了我的 DynamicEntity 对象,sellerAddress 对象在那里。

这是一个虚拟示例,我想如何将 DynamicEntity 用作 bean

package com.test.beans;

import java.io.InputStream;

import javax.annotation.PostConstruct;
import javax.enterprise.inject.Produces;
import javax.faces.bean.ViewScoped;
import javax.inject.Named;
import javax.xml.bind.JAXBException;

import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContextFactory;

@Named
@ViewScoped
public class CustomerHandler {

    DynamicJAXBContext jaxbContext;

    @PostConstruct
    public void init() throws JAXBException {
        InputStream xsdInputStream = getClass().getClassLoader().getResourceAsStream("customer.xsd");
        jaxbContext = DynamicJAXBContextFactory.createContextFromXSD(xsdInputStream, null, null,
                null);
    }

    @Produces
    @Named("Customer")
    public DynamicEntity createCustomer() {
        DynamicEntity customer = jaxbContext.newDynamicEntity("org.example.Customer");
        customer.set("name", "Jane Doe");
        DynamicEntity address = jaxbContext.newDynamicEntity("org.example.Address");
        address.set("street", "1 Any Street").set("city", "Any Town");
        customer.set("address", address);
        return customer;
    }

    public void save()
    {
        // do something
    }
}

customer.xsd 文件位于 src/main/resources

<xsd:schema 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
   xmlns="http://www.example.org" 
   targetNamespace="http://www.example.org"
   elementFormDefault="qualified">

   <xsd:complexType name="address">
      <xsd:sequence>
         <xsd:element name="street" type="xsd:string" minOccurs="0"/>
         <xsd:element name="city" type="xsd:string" minOccurs="0"/>
      </xsd:sequence>
   </xsd:complexType>

   <xsd:element name="customer">
      <xsd:complexType>
         <xsd:sequence>
            <xsd:element name="name" type="xsd:string" minOccurs="0"/>
            <xsd:element name="address" type="address" minOccurs="0"/>
         </xsd:sequence>
      </xsd:complexType>
   </xsd:element>

</xsd:schema>

我的测试页是customer.xhtml

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets">

<h:head>
    <title>Welcome to Customer Page</title>
</h:head>

<h:body>
    <h:form>
        <h:inputText value="#{Customer.name}" />
        <h:inputText value="#{Customer.address.street}" />
        <h:commandButton value="Submit" action="#{customerHandler.save()}" />
    </h:form>   
</h:body>
</html>

【问题讨论】:

  • 详细说明您的用例。您所做的参考是一个接口。你如何实现它,分享你的Invoice 课程?您如何使用/引用它,分享您访问该属性的方式?此外,您的堆栈跟踪的第一行是相当自我记录的,并为您提供代码可能有问题的线索。
  • @skuntsel 我已经在上面发布了一个示例。

标签: jsf jpa jsf-2 eclipselink


【解决方案1】:

DynamicEntity 类的文档向我们展示了它是一个接口,并且没有任何地方表明该接口提供了像getSellerAddress() 这样的良好的旧 POJO getter,它将返回所需的属性。当您尝试将值操作为 #{Customer.name} 时,这确实不起作用,因为没有 getName()/setName() 方法对。

DynamicEntity 接口公开的方法如下:

  • DynamicEntity#get(propertyName) 检索值并
  • DynamicEntity#set(propertyName, value) 预设值。

因此显然没有办法使用这些方法以标准 JSF 方式创建与 bean 属性的双边绑定。


您有以下选择来处理您的问题:

  1. 切换到 JPA 并创建像 @Entity public class Customer 这样的真实实体作为您的模型。这显然是更进一步的最佳方式和最佳实践;
  2. 为 JSF 表单创建一个占位符/支持 bean 以保留提交的值,并在操作方法中创建您的动态实体以供进一步操作。请注意,如果您决定遵循这条路线,您将错过 JSF 的所有要点;
  3. 很可能DynamicEntity 的实现(即从对DynamicJAXBContext#newDynamicEntity(String n) 的调用返回的实例)由Map 实现支持。调试以查看该调用返回的内容并将该信息应用于您的用例。如果它由带有名称为persistentMap 的公共getter/setter 对的映射支持,您的EL 将变为#{Customer.persistentMap['name']。请注意,这是一种不鼓励的做法,也是紧耦合的一个示例,并且在有支持集合的访问器的情况下是可能的。

总而言之,我强烈建议切换到 JPA 来解决您的用例。

【讨论】:

  • 1.由于业务需求,完全切换到 JPA 是不可能的。 2.不可行 3.不推荐的方式。我们可以使用动态代理吗,不知道 JSF 可以使用吗?有没有其他方法,比如针对这种特殊情况扩展EL解析机制?
猜你喜欢
  • 2016-10-09
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-14
相关资源
最近更新 更多