2

我正在寻找将嵌套属性的平面 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 转换库?

4

2 回答 2

0

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

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

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

并将“abcd ..”放入“。”递归地向下钻取拆分。

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

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

于 2010-07-02T03:24:23.570 回答
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 编组器的实现(例如 jersey-json),因此您还可以编组为其他格式:

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

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

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

于 2010-07-02T04:42:59.227 回答