700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 使用 JABX 将 Map<String String> 序列化成 <key>value</key>形式的字符串

使用 JABX 将 Map<String String> 序列化成 <key>value</key>形式的字符串

时间:2018-07-30 07:59:21

相关推荐

使用 JABX 将 Map<String String> 序列化成 <key>value</key>形式的字符串

前言:

JAXB(Java Architecture for XML Binding) 用于 XML 绑定的 Java 体系结构(JAXB)是允许 Java 开发人员将 Java 类映射到 XML 表示形式的软件框架。 JAXB 支持将 Java 对象编组为 XML,然后将 XML 解组为 Java 对象。

如下:

package com.c.utils.jaxb;import com.c.utils.LoggerUtils;import javax.xml.bind.JAXBContext;import javax.xml.bind.JAXBException;import javax.xml.bind.Marshaller;import javax.xml.bind.Unmarshaller;import java.io.File;/*** @author zhy*/public class JAXbUtils {private JAXbUtils() {}public static <T> void save(T obj, File file) {try {JAXBContext jc = JAXBContext.newInstance(obj.getClass());Marshaller jaxbMarshaller = jc.createMarshaller();jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);jaxbMarshaller.marshal(obj, file);// jaxbMarshaller.marshal(obj, System.out);} catch (JAXBException e) {LoggerUtils.getLogger(JAXbUtils.class).error(e.getMessage(), e);}}public static <T> T load(File file, Class<? extends T> type) {try {JAXBContext jc = JAXBContext.newInstance(type);Unmarshaller unmarshaller = jc.createUnmarshaller();return (T) unmarshaller.unmarshal(file);} catch (JAXBException e) {e.printStackTrace();}return null;}}

JAXB 与 Map<String,String>

JAXB 默认转换 map 的结果

JABX 默认将 Map<String,String> 序列化成:

<item><key>xxx<key><value>xxx<value></item>

如下:

package com.c.utils.jaxb;import org.junit.Assert;import org.junit.Test;import javax.xml.bind.annotation.XmlAccessType;import javax.xml.bind.annotation.XmlAccessorType;import javax.xml.bind.annotation.XmlRootElement;import java.io.File;import java.util.HashMap;import java.util.Map;public class JAXbUtilsTest {@Testpublic void saveMap() {Config config = new Config();config.map = new HashMap<>();String naturalSelection = "自然选择号";String blueSpace = "蓝色空间号";config.map.put(naturalSelection, "东方延绪");config.map.put(blueSpace, "褚岩");File file = new File("target/config.xml");JAXbUtils.save(config, file);Config newConfig = JAXbUtils.load(file, Config.class);Assert.assertNotNull(newConfig);Assert.assertEquals(config.map.get(naturalSelection), newConfig.map.get(naturalSelection));Assert.assertEquals(config.map.get(blueSpace), newConfig.map.get(blueSpace));}@XmlRootElement@XmlAccessorType(XmlAccessType.FIELD)static class Config {Map<String, String> map = new HashMap<>();}}

target/config.xml 文件内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><config><map><entry><key>自然选择号</key><value>东方延绪</value></entry><entry><key>蓝色空间号</key><value>褚岩</value></entry></map></config>

优化 JAXB 转换 MAP

理想状态,可以将其简化为以下形式( 标签名为key,内容为 value ):

<key>value</key>

则需要自定义转换器,将map转换为 w3c 的 Element 对象(其他自定义类型也可以这样实现),实现如下:

package com.c.utils.jaxb;import com.c.utils.LoggerUtils;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import javax.xml.bind.annotation.adapters.XmlAdapter;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import java.util.HashMap;import java.util.Map;public class MapAdapter extends XmlAdapter<Object, Map<String, String>> {public static final String TEXT = "#text";@Overridepublic Map<String, String> unmarshal(Object v) {Map<String, String> map = new HashMap<>();if (!(v instanceof Element)) {return map;}NodeList childNodes = ((Element) v).getChildNodes();for (int i = 0; i < childNodes.getLength(); i++) {Node item = childNodes.item(i);if (TEXT.equals(item.getNodeName())) {continue;}map.put(item.getNodeName(), item.getTextContent());}return map;}@Overridepublic Object marshal(Map<String, String> v) {Document document = null;try {document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();} catch (ParserConfigurationException e) {LoggerUtils.getLogger(getClass()).error(e.getMessage(), e);return null;}Element rootElement = document.createElement("map");document.appendChild(rootElement);for (Map.Entry<String, String> entry : v.entrySet()) {Element element = document.createElement(entry.getKey());element.setTextContent(entry.getValue());rootElement.appendChild(element);}return rootElement;}}

然后在需要序列化的 map 字段上加上 @XmlJavaTypeAdapter(MapAdapter.class) 注解。

@XmlRootElement@XmlAccessorType(XmlAccessType.FIELD)static class Config {@XmlElement(name = "properties")@XmlJavaTypeAdapter(MapAdapter.class)Map<String, String> map = new HashMap<>();}

修改后 target/config.xml 文件内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><config><properties><自然选择号>东方延绪</自然选择号><蓝色空间号>褚岩</蓝色空间号></properties></config>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。