深度bean拷贝与null属性实例化的策略

时间:2010-07-02 02:56:53

标签: java reflection javabeans apache-commons-beanutils

我正在寻找一种最简单的方法来对平面Map进行深层复制< String,String>对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转换库吗?

2 个答案:

答案 0 :(得分:0)

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

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

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

然后把“a.b.c.d ...”递归地向下钻取“。”

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

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

答案 1 :(得分:0)

我认为你可能会比这更困难。我要做的是序列化标记或其他格式。我不确定你的要求是什么,但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 marshaller还有其他一些实现(例如jersey-json),所以你也可以用其他格式编组:

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

您是否需要使用地图?如果没有,你只是解决方案是一些复杂的Reflections实用程序,希望像GSON库这样的东西可以促进复杂性。

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