我编写了一个JAXB映射,它将子列表存储在 LinkedHashMap<String, Object>
中的根元素内,而不是通过特定的 XmlJavaTypeAdapter
维护的 Collection<Object>
. 下面是一个示例:
@XmlRootElement
public class Parent {
@XmlJavaTypeAdapter(ListToMapAdapter.class)
@XmlElement
private LinkedHashMap<String, Child> children;
...
}
密钥是根据子标记的属性构建的(例如 <child id="key">
给 Map.Entry<String, Child>
,如 {key => child}
.
我的一个同事说它的设计很糟糕,并且这个应该在负责解组XML的对象中 . 我不同意他的看法 . 以下是这种方法的一些优点和缺点 . 您认为哪种设计最好?您认为哪些优点和缺点可以完成辩论?
Goal of this design:
Map
能够有效地搜索具有标准的孩子(我的样本中的关键字),而不是通过迭代搜索Collecion .
Pros:
-
用于搜索和过滤子列表的责任在对象的最近处,父对象负责检索和过滤其子项,
-
_4448560_的构建由JAXB在解组时自动生成:优雅,高效, preserve from building the Map with a post process of the list after umarshalling (iteration) ,
-
不同读者中的同一个对象仍然具有过滤其子女的能力,
-
主观,这真的是一种很好的方式:),
-
如果
@XmlJavaTypeAdapter
存在,部分原因是这一点(Web上的大量样本) .
Cons (有些来自我的同事) :
-
JAXB限制约束代码到具体实现而不是接口:无法在我的示例中声明
Map<String, Child>
(在解组时不能由JAXB实例化), -
也许(和我的同事的论点),它不是映射对象(根据他的简单POJO)的角色有这样的行为,
-
@XmlJavaTypeAdapter
仅用于将简单对象转换为特定类型:例如xs:date
到Joda timeCalendar
.
在此先感谢您的2美分 .
2 回答
我总是建议人们为他们的应用设计最好的模型 . 然后让JAXB处理将其映射到XML的难度 . 在这种情况下,如果父母有一个孩子的 Map 是有意义的,那么通过这种方式一定模仿它 . JAXB确实支持Map,但是使用您描述的XML表示法,您将需要使用XmlAdapter . 有关更多信息,请参阅
所有优点似乎都合理 . 没有任何缺点是有效的:
正如您在使用@XmlJavaTypeAdaper时从上面的示例中看到的那样,您的属性不限于Map的具体实现 .
XmlAdapter是POJO模型的外部,因此模型没有到/来自 Map 行为的列表 .
XmlAdapter对于任何难以映射的用例都是一个全部捕获 . 它不仅限于简单的对象 . 常见的用例是映射Map的实例 .
如果要消除包装元素,则可以在MOXy JAXB实现中使用@XmlPath扩展 . 我的博客文章中的Foo类将略有修改:
有关更多信息,请参阅
http://bdoughan.blogspot.com/2010/07/xpath-based-mapping.html
http://bdoughan.blogspot.com/2010/09/xpath-based-mapping-geocode-example.html
感谢您的亮点 . 我现在确信我的方式是好的方式,我的同事需要修改他的观点:-) .
我看过你的博文 . 实际上,我已成功实现与接口上的适配器解组 . 不知道为什么到目前为止我失败了 .
仍然是一个遗留问题,我仍然没有实现映射未嵌套在元素包装器中的元素列表,如下所述:http://weblogs.java.net/blog/2005/04/22/xmladapter-jaxb-ri-ea . 像你一样,在JavaDoc中解释它,我需要在你的例子中使用一个中间包装器对象(
MyMapType
) . 是否可以直接创建XmlJavaTypeAdapter<List<WrappedObject>, Map<String, WrappedObject>>
而不是将List
放在ListWrapper<WrappedObject>
中?我当然会在S.O.中单独发表这个问题的帖子 . 办法 .