文章21 | 阅读 8249 | 点赞0
摘要: JAXB 作为JDK的一部分,能便捷地将Java对象与XML进行相互转换,本教程从实际案例出发来讲解JAXB 2 的那些事儿。完整版目录
上节介绍的是关于List的转换方式,这一节开始,将基于Map
这种数据类型做转换。
这里的 Product.java
含有一个Map类型的属性。
public class Product {
private String id;
private Map<String, String> item;
// ignore setters/getters
}
首先来测试一下,和之前的章节一样的结构,不多做解释:
@Test
public void test1() throws JAXBException {
Map<String, String> map = new HashMap<>();
map.put("衣服", "大衣");
map.put("裤子", "西裤");
Product product = new Product();
product.setId("1401");
product.setItem(map);
JAXB.marshal(product, System.out);
}
看一下结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<product>
<id>1401</id>
<item>
<entry>
<key>衣服</key>
<value>大衣</value>
</entry>
<entry>
<key>裤子</key>
<value>西裤</value>
</entry>
</item>
</product>
结果比较奇怪,每一组Map数据被解析成了 <entry>
、<key>
、<value>
结构,通过之前的知识,改变<product>
节点下的<id>
、<item>
的值是可以轻松做到的。而这里的<key>
、<value>
并不是我们希望显示的节点名称,这就需要进行改造了。
改造需要的代码量比较多,因为JAXB原生不指定Map的自定义操作。也可以说JAXB不支持Map这种数据类型。所以需要使用到适配器来扩展Jaxb的功能。
首先定义一个类,其中只有两个字段,为了简单,可以不写setters/getters方法。通过这种方式模拟一个Map,只包含key/value,也就是first/second,这个名称就是XML的节点显示名称。
public class XmlMap {
public String first;
public String second;
}
自定义一个Adapter
,这里将所有的代码都展示出来。
public class MapAdapter extends XmlAdapter<XmlMap[], Map<String, String>>{
@Override
public Map<String, String> unmarshal(XmlMap[] v) throws Exception {
Map<String, String> map = new HashMap<>();
for(int i=0;i<v.length;i++) {
XmlMap pairs = v[i];
map.put(pairs.first, pairs.second);
}
return map;
}
@Override
public XmlMap[] marshal(Map<String, String> v) throws Exception {
XmlMap[] xmlMap = new XmlMap[v.size()];
int index = 0;
for(Map.Entry<String, String> entry: v.entrySet()) {
XmlMap xm = new XmlMap();
xm.first = entry.getKey();
xm.second = entry.getValue();
xmlMap[index++] = xm;
}
return xmlMap;
}
}
@XmlJavaTypeAdapter
JAXB能够内置支持List和Set集合,但是对于Map的支持需要自己处理。它继承自抽象类XmlAdapter<ValueType,BoundType>
类型参数:
这里的Map对于JAXB是一个未知类型,但是XmlMap[]
却是已知的对象数组类型。通过中间的转化赋值,可以使XmlMap[]
与Map
相互转化,从而让Jaxb知道数据如何处理。
在之前的Product中,在Map上加上注解@XmlJavaTypeAdapter(MapAdapter.class)
。
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Product2 {
private String id;
@XmlJavaTypeAdapter(MapAdapter.class)
public Map<String, String> category;
// setters, getters
测试一下:
@Test
public void test2() throws JAXBException {
Map<String, String> map = new HashMap<>();
map.put("衣服", "大衣");
map.put("裤子", "西裤");
Product2 product = new Product2();
product.setId("1402");
product.setCategory(map);
JAXB.marshal(product, System.out);
}
得到的结果:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<product2>
<id>1402</id>
<category>
<item>
<first>衣服</first>
<second>大衣</second>
</item>
<item>
<first>裤子</first>
<second>西裤</second>
</item>
</category>
</product2>
上面的所有节点名称除了item
都是可以通过已经讲述的方法改变的。
可以在GitHub找到完整代码。
本节代码均在该包下:package com.example.demo.lesson14;
本节介绍了 JAXB 中Map 的相关转化。下节开始,将开始讲述Jaxb在 Spring 项目中使用案例。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://jiangchao.blog.csdn.net/article/details/84000603
内容来源于网络,如有侵权,请联系作者删除!