发布于2021-01-01 15:56 阅读(1107) 评论(0) 点赞(11) 收藏(4)
JAXB(Java Architecture for XML Binding)是J2SE和J2EE平台的一部分,让开发者能够快速完成Java类和XML的互相映射。一些具体的介绍和使用可以到此细看:JAXB教程
java与xml互转工具类:
- import javax.xml.bind.JAXBContext;
- import javax.xml.bind.JAXBException;
- import javax.xml.bind.Marshaller;
- import javax.xml.bind.Unmarshaller;
- import java.io.StringReader;
- import java.io.StringWriter;
-
- /**
- * Jaxb工具类 xml和java类相互转换
- * @author
- * @version 1.0
- * @date: 2020/12/9
- */
-
- public class JaxbXmlUtil {
-
- public static final String DEFAULT_ENCODING = "UTF-8";
-
- /**
- * java对象转换成xml 默认编码UTF-8
- *
- * @param obj 待转化的对象
- * @return xml格式字符串
- * @throws Exception JAXBException
- */
- public static String convertToXml(Object obj) throws JAXBException {
- return convertToXml(obj, DEFAULT_ENCODING);
- }
-
- /**
- * java对象转换成xml
- *
- * @param obj 待转化的对象
- * @param encoding 编码
- * @return xml格式字符串
- * @throws Exception JAXBException
- */
- public static String convertToXml(Object obj, String encoding) throws JAXBException {
- String result = null;
-
- JAXBContext context = JAXBContext.newInstance(obj.getClass());
- Marshaller marshaller = context.createMarshaller();
- // 指定是否使用换行和缩排对已编组 XML 数据进行格式化的属性名称。
- marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
- marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
-
- StringWriter writer = new StringWriter();
- marshaller.marshal(obj, writer);
- result = writer.toString();
-
- return result;
- }
-
- /**
- * xml转换成JavaBean
- *
- * @param xml xml格式字符串
- * @param t 待转化的对象
- * @return 转化后的对象
- * @throws Exception JAXBException
- */
- @SuppressWarnings("unchecked")
- public static <T> T convertToJavaBean(String xml, Class<T> t) throws JAXBException {
- T obj = null;
- JAXBContext context = JAXBContext.newInstance(t);
- Unmarshaller unmarshaller = context.createUnmarshaller();
- obj = (T) unmarshaller.unmarshal(new StringReader(xml));
- return obj;
- }
- }
使用工具类,再结合jaxb注解使用,可以轻松实现java与xml之间的互转;注意必须要有对应的注解来告诉工具包,实体类哪里是更元素,哪里是子元素,以及元素中的属性
- import com.gbiac.tmc.newenergy.bo.FlightSegment;
- import lombok.AllArgsConstructor;
- import lombok.Builder;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.beans.factory.annotation.Value;
-
- import javax.xml.bind.annotation.*;
- import java.util.List;
-
- /**
- * yeesky验舱验价参数"request" xml格式
- * @author
- * @version 1.0
- * @date: 2020/12/29
- */
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @Builder
- @XmlAccessorType(XmlAccessType.FIELD)
- @XmlRootElement(name="ABE_PATByFlights_1_3")
- public class YeeskyCheckCabinPriceRequestDto {
-
- /**
- * <!-- 数据类型:字符型 -->
- * <!-- 长 度: -->
- * <!-- 说 明:指定运价指令,如:PAT:A*CH (必填) -->
- */
- @XmlElement(name = "PatPara",required =true)
- private String patPara;
-
- @XmlElementWrapper(name ="FlightSegments",required =true )
- @XmlElement(name ="FlightSegment",required =true )
- private List<FlightSegment> flightSegments;
-
- /**
- * <!-- 说 明:指定运价指令(与FlightSegments其中一项必填) -->
- */
- @XmlElement(name = "PNR",nillable = true,required = true)
- private String pnr;
-
- /**
- * <!-- 说 明: PNR选项,"X"表示航司配置PAT小编码 -->
- */
- @XmlElement(name = "PNROption",nillable = true,required = true)
- private String pnrOption;
- /**
- *<!-- 说 明:折扣代码(非必填) -->
- */
- @XmlElement(name = "PriceType",nillable = true,required = true)
- private String priceType;
- /**
- * <!-- 说 明: 运价基础(非必填) -->
- */
- @XmlElement(name = "Farebasis",nillable = true,required = true)
- @Value("C9CNA001L")
- private String fareBasis;
- /**
- * <!-- 说 明: 允许报价的航段状态(非必填) -->
- */
- @XmlElement(name = "AllowActionCode",nillable = true,required = true)
- private String allowActionCode;
- /**
- * <!-- 说 明: 允许不确定的价格项,取值范围:Y/N默认(非必填) -->
- */
- @XmlElement(name = "AllowUncertainPrice",nillable = true,required = true)
- private String allowUncertainPrice;
-
-
- }
其中@XmlElement注解中的参数,那么是元素标签名例如第一个属性对应的xml标签为<PriceType>,required=true,表示这个元素标签是必须的,即使该标签元素没有值,也要转换显示出来,例如<PNR></PNR>这个,是没有给该标签元素赋值的,但是仍然会显示出来,如果没有加required=true,那么该参数值required默认为false,当pnr=""或pnr=null时,也就是没有赋予有效值的时候,该元素不转换显示出来,那么最后的xml文档中就没有了该元素,nillable=true,表示该元素可以为null,就是当该java类的对应属性如pnr=null时,也就是没有对该属性初始化赋值,这时候,该属性要转换成的对应的xml文档元素也是null,此时转换为xml标签元素会出错,加上这个就不会报错了,同时显示格式会是最下边那张截图里的那样的元素显示方式,如: <PNR xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
对于List性质的属性,也就是在xml文档会多次出现相同的标签元素的,list属性对应的xml注解就是@XmlElementWrapper,然后下边加的注解就是会出现多个相同标签元素的标签名,还是用@XmlElement
由于list集合中包含的也是对象,所以,对象也需要加xml注解,来表示xml中所在位置
例如
@XmlElementWrapper(name ="FlightSegments",required =true )
@XmlElement(name ="FlightSegment",required =true )
private List<FlightSegment> flightSegments;
对应的类FlightSegment
- package com.gbiac.tmc.newenergy.bo;
-
- import com.gbiac.tmc.newenergy.utils.LocalDate2XmlAdapter;
- import lombok.AllArgsConstructor;
- import lombok.Builder;
- import lombok.Data;
- import lombok.NoArgsConstructor;
-
- import javax.xml.bind.annotation.XmlAccessType;
- import javax.xml.bind.annotation.XmlAccessorType;
- import javax.xml.bind.annotation.XmlElement;
- import javax.xml.bind.annotation.XmlRootElement;
- import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
- import java.time.LocalDate;
-
- /**
- * yeesky验舱验价请求参数中的FlightSegment参数部分
- * @author
- * @version 1.0
- * @date: 2020/12/29
- */
- @Data
- @NoArgsConstructor
- @AllArgsConstructor
- @Builder
- @XmlAccessorType(value = XmlAccessType.FIELD)
- @XmlRootElement(name = "FlightSegment")
- public class FlightSegment {
-
- /**
- * 承运人(值为:航空公司二字码)
- */
-
- @XmlElement(name = "Carrier",required =true)
- private String carrier;
- /**
- * 航班号
- */
- @XmlElement(name = "FlightNo",required =true)
- private String flightNo;
-
- /**
- * 起飞机场三字码
- */
- @XmlElement(name = "BoardPoint")
- private String departureAirportCode;
- /**
- * 到达机场三字码
- */
- @XmlElement(name = "OffPoint")
- private String arrivalAirportCode;
- /**
- * 出发日期
- */
- @XmlElement(name = "DepatureDate",required =true)
- // 将localDate类型值转换为xml元素值适配器(适配格式"yyyy-MM-dd")
- @XmlJavaTypeAdapter(LocalDate2XmlAdapter.class)
- private LocalDate departureDate;
- /**
- * 舱位代码
- */
- @XmlElement(name = "ClassCode")
- private String cabinCode;
- /**
- * 行动代码
- */
- @XmlElement(name = "ActionCode")
- private String actionCode;
- }
最后使用工具类转换映射后的结果就是这样(java对象值是由request请求体中json格式传递过来的)
对于转换java中的日期属性为xml元素,并能成功给xml元素赋予日期格式,则需要另外的适配器,才能赋予我们需要的日期格式显示出来
例如:
- <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
- <ABE_PATByFlights_1_3>
- <FlightSegments>
- <FlightSegment>
- <Carrier>SC</Carrier>
- <FlightNo>9009</FlightNo>
- <BoardPoint>CAN</BoardPoint>
- <OffPoint>LYI</OffPoint>
- <DepatureDate>2020-12-31</DepatureDate>
- <ClassCode>V</ClassCode>
- </FlightSegment>
- </FlightSegments>
<DepatureDate>这个标签需要一个日期格式的值,并且是yyyy-MM-dd这种格式的
- /**
- * 出发日期
- */
- @XmlElement(name = "DepatureDate",required =true)
- // 将localDate类型值转换为xml元素值适配器(适配格式"yyyy-MM-dd")
- @XmlJavaTypeAdapter(LocalDate2XmlAdapter.class)
- private LocalDate departureDate;
对应的适配器:
- import javax.xml.bind.annotation.adapters.XmlAdapter;
- import java.time.LocalDate;
- import java.time.format.DateTimeFormatter;
-
- /**
- * java对象转换LocalDate格式适配器
- * @author
- * @version 1.0
- * @date: 2020/12/10
- */
-
- public class LocalDate2XmlAdapter extends XmlAdapter<String, LocalDate> {
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-
- @Override
- public LocalDate unmarshal(String xml) throws Exception {
- return LocalDate.parse(xml,formatter);
- }
-
- @Override
- public String marshal(LocalDate localDate) throws Exception {
- return localDate.format(formatter);
- }
- }
每个月至少一篇博客,这个月一直在写一个新模块,比较忙,所以今天才想起来要写一篇博客,也没想到要写什么,为了不断更博客,所以就暂且随便写了这个!
原文链接:https://blog.csdn.net/u011174699/article/details/111998648
作者:lovejava
链接:http://www.javaheidong.com/blog/article/45771/c1ccdc5b606c79ca0ae0/
来源:java黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 java黑洞网 All Rights Reserved 版权所有,并保留所有权利。京ICP备18063182号-2
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!