【问题标题】:Deep bean copy with strategy for null property instantiation具有空属性实例化策略的深度 bean 复制
【发布时间】:2010-07-02 02:56:52
【问题描述】:

我正在寻找将嵌套属性的平面 Map 深度复制到 bean 的最简单方法。一些嵌套属性是我想为其提供实例化策略的接口。例如:

Map<String, String> customer = new Map<String, String>();
customers.put("id", "123");
customers.put("address.line1", "221B Baker St.");

public class Customer {
  private int id;
  private Address address; //address is an interface
  ... getters/setters ...
}

请注意,我不想提供显式映射,只是为接口提供具体实例的策略。我假设 commons-beanutils 可以做到这一点,但他们是开放的JIRA 功能票。具有类似功能的库是 Google GSON,它提供了一个名为 InstanceCreator 的接口。

我已经在 beanutils 之上实现了一个解决方案,但是有没有内置这个功能的 bean 转换库?

【问题讨论】:

    标签: java reflection javabeans apache-commons-beanutils


    【解决方案1】:

    你有点表达两种不同的东西。更容易做的是你最初描述的,深度嵌套的字符串映射。所以

    put("id", "1")  -> map.put("id", "1")
    put("address.line1", "221b")  -> ((Map)map.get("address")).put("221B")
    

    (为简洁起见,我忽略了实际的安全检查是那里的地图,如果是,则初始化,yadda yadda,所有这些都让我们喜欢 java 简洁的做事方式。)

    并把“a.b.c.d...”只是递归地通过“.”向下钻取拆分

    如果你真的想要“地址”。 (因为您在示例中引用了地址类)来引用地址类型的对象,这有点复杂,您将需要将前缀识别为类的东西,最好是响应地图的自定义东西接口,可以在遍历树时轻松实例化,并且知道如何从输入字符串创建自身的对象。

    第一个的beanutils实现细节我不太清楚,写起来也不是太难。但是字符串的嵌套映射很容易。您可以使用序列化(因为 hashmap 和字符串序列化)或使用 json 库轻松打包它,这应该采用嵌套字符串映射,完全没有问题(google gson 运行良好)。

    【讨论】:

    • 我根据您的反馈稍微修改了问题。我只是想处理嵌套属性的平面图。另外,我查看了 Google GSON,它具有我正在寻找的 InstanceCreator 的概念——除了我要使用 map -> bean 而不是 map -> json。
    【解决方案2】:

    我认为您可能让这件事变得更加困难。我要做的是在标记或其他格式之间进行序列化。我不确定您的要求是什么,但JAXBXStream 等所有优秀的编组人员都可以做到这一点。

    使用 JAXB,您可以执行以下操作:

    @XmlRootElement(name="customer")
    public class Customer
    {
        private int id;
        private Address address;
    }
    
    @XmlRootElement(name="address")
    public class Address
    {
        private String city;
    }
    

    并使用以下 XML:

    <customer>
        <id>1234</id>
        <address>
            <city>Kansas City</city>
        </address>
    </customer>
    

    ...可以来回编组和解组。此外,还有其他几种 JAXB 编组器的实现(例如 jersey-json),因此您还可以编组为其他格式:

    {
        "customer": 
        {
            "id":1234,
            "address": 
            {
                 "city":"Kansas City"
            }
        }
    }
    

    您需要使用地图有什么特别的原因吗?如果没有,您唯一的解决方案是一些复杂的反射实用程序,希望 GSON 库之类的东西可以简化复杂性。

    编辑:刚刚看到你关于不想要映射的宣传......我不太明白。使用序列化后,任何其他类似的方法似乎都不值得。

    【讨论】:

    • 我正在做一个演示,其中我已经有一些我必须将属性复制到的 bean。我已经将数据作为平面索引图;它来自文档存储。我当然可以使用 JSON,但是看到我已经拥有其他格式的数据,我只想使用手头的数据。当我为生产目的编写此代码时,我可能会完全使用其他方法来映射数据。
    猜你喜欢
    • 1970-01-01
    • 2022-01-08
    • 2020-04-04
    • 2020-10-26
    • 1970-01-01
    • 2011-01-10
    • 2019-06-21
    • 1970-01-01
    • 2021-02-15
    相关资源
    最近更新 更多