规范
The Jakarta XML Binding provides an API and tools that automate the mapping between XML documents and Java objects.
规范文档:https://jakarta.ee/specifications/xml-binding/
实现
官方认证实现:https://eclipse-ee4j.github.io/jaxb-ri/
依赖下载:https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-ri,将传递依赖:
1 2 3 4
| <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> </dependency>
|
示例
本文演示如何生成和解析 XML,主要涉及以下常用注解,更多注解可以自行尝试:
1 2 3 4
| @XmlRootElement @XmlElement @XmlAttribute @XmlValue
|
实体类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| @Getter @ToString @Builder @NoArgsConstructor @AllArgsConstructor @XmlRootElement(name = "head") class Head { @XmlElement(name = "trade_code") private String tradeCode;
@XmlElement(name = "trade_date") private String tradeDate;
@XmlElement(name = "trade_time") private String tradeTime;
@XmlElement(name = "serial_no") private String serialNo;
@XmlElement(name = "parent") private Parent parent; }
@Getter @ToString @Builder @NoArgsConstructor @AllArgsConstructor @XmlRootElement class Parent { @XmlElement private List<Child> child; }
@Getter @ToString @Builder @NoArgsConstructor @AllArgsConstructor class Child { @XmlAttribute private String key;
@XmlValue private String value; }
|
XML 工具类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| @Slf4j public class XmlUtils {
private static final Map<String, JAXBContext> JAXB_CONTEXT_MAP = new HashMap<>();
public static <T> String toXml(T t) { if (t == null) { log.warn("[XmlUtils toXml] params is null"); return null; }
JAXBContext jaxbContext = getJAXBContext(t.getClass()); Marshaller jaxbMarshaller; try (StringWriter stringWriter = new StringWriter()) { jaxbMarshaller = jaxbContext.createMarshaller(); jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8"); jaxbMarshaller.marshal(t, stringWriter); return stringWriter.toString(); } catch (JAXBException | IOException e) { log.error("[XmlUtils toXml] exception", e); } return null; }
public static <T> T unXml(String xml, Class<T> clazz) { if (xml == null || xml.isEmpty()) { log.warn("[XmlUtils unXml] xml is null"); return null; }
JAXBContext jaxbContext = getJAXBContext(clazz); try { Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); StringReader reader = new StringReader(xml); @SuppressWarnings("unchecked") T unmarshal = (T) unmarshaller.unmarshal(reader); return unmarshal; } catch (JAXBException e) { log.error("[XmlUtils unXml] exception", e); } return null; }
private static JAXBContext getJAXBContext(Class clazz) { JAXBContext jaxbContext = JAXB_CONTEXT_MAP.get(clazz.getName()); if (jaxbContext == null) { try { jaxbContext = JAXBContext.newInstance(clazz); JAXB_CONTEXT_MAP.put(clazz.getName(), jaxbContext); } catch (JAXBException e) { log.error(e.getMessage(), e); } } return jaxbContext; }
}
|
生成 XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @Test public void testToXml() { LocalDateTime now = LocalDateTime.now(); Child child = Child.builder() .key("key") .value("value") .build();
Parent parent = Parent.builder() .child(Arrays.asList(child, child)) .build();
Head head = Head.builder() .tradeCode("XT-001") .tradeDate(now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))) .tradeTime(now.format(DateTimeFormatter.ofPattern("HH:mm:ss"))) .serialNo(UUID.randomUUID().toString()) .parent(parent) .build(); String xml = XmlUtils.toXml(head); log.info(xml); }
|
输出结果:
1 2 3 4 5 6 7 8 9 10 11
| <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <head> <trade_code>XT-001</trade_code> <trade_date>2020-03-19</trade_date> <trade_time>18:39:28</trade_time> <serial_no>114d2c0c-30a8-4275-982c-f8eba86cbadb</serial_no> <parent> <child key="key">value</child> <child key="key">value</child> </parent> </head>
|
解析 XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Test public void testUnXml() { String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + "<head>\n" + " <trade_code>XT-001</trade_code>\n" + " <trade_date>2020-03-19</trade_date>\n" + " <trade_time>18:39:28</trade_time>\n" + " <serial_no>114d2c0c-30a8-4275-982c-f8eba86cbadb</serial_no>\n" + " <parent>\n" + " <child key=\"key\">value</child>\n" + " <child key=\"key\">value</child>\n" + " </parent>\n" + "</head>"; Head head = XmlUtils.unXml(xml, Head.class); log.info(head.toString()); }
|
输出结果
1
| Head(tradeCode=XT-001, tradeDate=2020-03-19, tradeTime=18:39:28, serialNo=114d2c0c-30a8-4275-982c-f8eba86cbadb, parent=Parent(child=[Child(key=key, value=value), Child(key=key, value=value)]))
|
参考
https://jakarta.ee/specifications/xml-binding/
https://en.wikipedia.org/wiki/Jakarta_XML_Binding