程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-06(1)

JAXB处理java对象与xml格式之间的转换

发布于2021-01-01 15:56     阅读(1107)     评论(0)     点赞(11)     收藏(4)


JAXB(Java Architecture for XML Binding)是J2SE和J2EE平台的一部分,让开发者能够快速完成Java类和XML的互相映射。一些具体的介绍和使用可以到此细看:JAXB教程

java与xml互转工具类:

  1. import javax.xml.bind.JAXBContext;
  2. import javax.xml.bind.JAXBException;
  3. import javax.xml.bind.Marshaller;
  4. import javax.xml.bind.Unmarshaller;
  5. import java.io.StringReader;
  6. import java.io.StringWriter;
  7. /**
  8. * Jaxb工具类 xml和java类相互转换
  9. * @author
  10. * @version 1.0
  11. * @date: 2020/12/9
  12. */
  13. public class JaxbXmlUtil {
  14. public static final String DEFAULT_ENCODING = "UTF-8";
  15. /**
  16. * java对象转换成xml 默认编码UTF-8
  17. *
  18. * @param obj 待转化的对象
  19. * @return xml格式字符串
  20. * @throws Exception JAXBException
  21. */
  22. public static String convertToXml(Object obj) throws JAXBException {
  23. return convertToXml(obj, DEFAULT_ENCODING);
  24. }
  25. /**
  26. * java对象转换成xml
  27. *
  28. * @param obj 待转化的对象
  29. * @param encoding 编码
  30. * @return xml格式字符串
  31. * @throws Exception JAXBException
  32. */
  33. public static String convertToXml(Object obj, String encoding) throws JAXBException {
  34. String result = null;
  35. JAXBContext context = JAXBContext.newInstance(obj.getClass());
  36. Marshaller marshaller = context.createMarshaller();
  37. // 指定是否使用换行和缩排对已编组 XML 数据进行格式化的属性名称。
  38. marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  39. marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
  40. StringWriter writer = new StringWriter();
  41. marshaller.marshal(obj, writer);
  42. result = writer.toString();
  43. return result;
  44. }
  45. /**
  46. * xml转换成JavaBean
  47. *
  48. * @param xml xml格式字符串
  49. * @param t 待转化的对象
  50. * @return 转化后的对象
  51. * @throws Exception JAXBException
  52. */
  53. @SuppressWarnings("unchecked")
  54. public static <T> T convertToJavaBean(String xml, Class<T> t) throws JAXBException {
  55. T obj = null;
  56. JAXBContext context = JAXBContext.newInstance(t);
  57. Unmarshaller unmarshaller = context.createUnmarshaller();
  58. obj = (T) unmarshaller.unmarshal(new StringReader(xml));
  59. return obj;
  60. }
  61. }

使用工具类,再结合jaxb注解使用,可以轻松实现java与xml之间的互转;注意必须要有对应的注解来告诉工具包,实体类哪里是更元素,哪里是子元素,以及元素中的属性

  1. import com.gbiac.tmc.newenergy.bo.FlightSegment;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Builder;
  4. import lombok.Data;
  5. import lombok.NoArgsConstructor;
  6. import org.springframework.beans.factory.annotation.Value;
  7. import javax.xml.bind.annotation.*;
  8. import java.util.List;
  9. /**
  10. * yeesky验舱验价参数"request" xml格式
  11. * @author
  12. * @version 1.0
  13. * @date: 2020/12/29
  14. */
  15. @Data
  16. @NoArgsConstructor
  17. @AllArgsConstructor
  18. @Builder
  19. @XmlAccessorType(XmlAccessType.FIELD)
  20. @XmlRootElement(name="ABE_PATByFlights_1_3")
  21. public class YeeskyCheckCabinPriceRequestDto {
  22. /**
  23. * <!-- 数据类型:字符型 -->
  24. * <!-- 长 度: -->
  25. * <!-- 说 明:指定运价指令,如:PAT:A*CH (必填) -->
  26. */
  27. @XmlElement(name = "PatPara",required =true)
  28. private String patPara;
  29. @XmlElementWrapper(name ="FlightSegments",required =true )
  30. @XmlElement(name ="FlightSegment",required =true )
  31. private List<FlightSegment> flightSegments;
  32. /**
  33. * <!-- 说 明:指定运价指令(与FlightSegments其中一项必填) -->
  34. */
  35. @XmlElement(name = "PNR",nillable = true,required = true)
  36. private String pnr;
  37. /**
  38. * <!-- 说 明: PNR选项,"X"表示航司配置PAT小编码 -->
  39. */
  40. @XmlElement(name = "PNROption",nillable = true,required = true)
  41. private String pnrOption;
  42. /**
  43. *<!-- 说 明:折扣代码(非必填) -->
  44. */
  45. @XmlElement(name = "PriceType",nillable = true,required = true)
  46. private String priceType;
  47. /**
  48. * <!-- 说 明: 运价基础(非必填) -->
  49. */
  50. @XmlElement(name = "Farebasis",nillable = true,required = true)
  51. @Value("C9CNA001L")
  52. private String fareBasis;
  53. /**
  54. * <!-- 说 明: 允许报价的航段状态(非必填) -->
  55. */
  56. @XmlElement(name = "AllowActionCode",nillable = true,required = true)
  57. private String allowActionCode;
  58. /**
  59. * <!-- 说 明: 允许不确定的价格项,取值范围:Y/N默认(非必填) -->
  60. */
  61. @XmlElement(name = "AllowUncertainPrice",nillable = true,required = true)
  62. private String allowUncertainPrice;
  63. }

其中@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

  1. package com.gbiac.tmc.newenergy.bo;
  2. import com.gbiac.tmc.newenergy.utils.LocalDate2XmlAdapter;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Builder;
  5. import lombok.Data;
  6. import lombok.NoArgsConstructor;
  7. import javax.xml.bind.annotation.XmlAccessType;
  8. import javax.xml.bind.annotation.XmlAccessorType;
  9. import javax.xml.bind.annotation.XmlElement;
  10. import javax.xml.bind.annotation.XmlRootElement;
  11. import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
  12. import java.time.LocalDate;
  13. /**
  14. * yeesky验舱验价请求参数中的FlightSegment参数部分
  15. * @author
  16. * @version 1.0
  17. * @date: 2020/12/29
  18. */
  19. @Data
  20. @NoArgsConstructor
  21. @AllArgsConstructor
  22. @Builder
  23. @XmlAccessorType(value = XmlAccessType.FIELD)
  24. @XmlRootElement(name = "FlightSegment")
  25. public class FlightSegment {
  26. /**
  27. * 承运人(值为:航空公司二字码)
  28. */
  29. @XmlElement(name = "Carrier",required =true)
  30. private String carrier;
  31. /**
  32. * 航班号
  33. */
  34. @XmlElement(name = "FlightNo",required =true)
  35. private String flightNo;
  36. /**
  37. * 起飞机场三字码
  38. */
  39. @XmlElement(name = "BoardPoint")
  40. private String departureAirportCode;
  41. /**
  42. * 到达机场三字码
  43. */
  44. @XmlElement(name = "OffPoint")
  45. private String arrivalAirportCode;
  46. /**
  47. * 出发日期
  48. */
  49. @XmlElement(name = "DepatureDate",required =true)
  50. // 将localDate类型值转换为xml元素值适配器(适配格式"yyyy-MM-dd")
  51. @XmlJavaTypeAdapter(LocalDate2XmlAdapter.class)
  52. private LocalDate departureDate;
  53. /**
  54. * 舱位代码
  55. */
  56. @XmlElement(name = "ClassCode")
  57. private String cabinCode;
  58. /**
  59. * 行动代码
  60. */
  61. @XmlElement(name = "ActionCode")
  62. private String actionCode;
  63. }

最后使用工具类转换映射后的结果就是这样(java对象值是由request请求体中json格式传递过来的)

对于转换java中的日期属性为xml元素,并能成功给xml元素赋予日期格式,则需要另外的适配器,才能赋予我们需要的日期格式显示出来

例如:

  1. <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  2. <ABE_PATByFlights_1_3>
  3. <FlightSegments>
  4. <FlightSegment>
  5. <Carrier>SC</Carrier>
  6. <FlightNo>9009</FlightNo>
  7. <BoardPoint>CAN</BoardPoint>
  8. <OffPoint>LYI</OffPoint>
  9. <DepatureDate>2020-12-31</DepatureDate>
  10. <ClassCode>V</ClassCode>
  11. </FlightSegment>
  12. </FlightSegments>

<DepatureDate>这个标签需要一个日期格式的值,并且是yyyy-MM-dd这种格式的

  1. /**
  2. * 出发日期
  3. */
  4. @XmlElement(name = "DepatureDate",required =true)
  5. // 将localDate类型值转换为xml元素值适配器(适配格式"yyyy-MM-dd")
  6. @XmlJavaTypeAdapter(LocalDate2XmlAdapter.class)
  7. private LocalDate departureDate;

对应的适配器:

  1. import javax.xml.bind.annotation.adapters.XmlAdapter;
  2. import java.time.LocalDate;
  3. import java.time.format.DateTimeFormatter;
  4. /**
  5. * java对象转换LocalDate格式适配器
  6. * @author
  7. * @version 1.0
  8. * @date: 2020/12/10
  9. */
  10. public class LocalDate2XmlAdapter extends XmlAdapter<String, LocalDate> {
  11. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
  12. @Override
  13. public LocalDate unmarshal(String xml) throws Exception {
  14. return LocalDate.parse(xml,formatter);
  15. }
  16. @Override
  17. public String marshal(LocalDate localDate) throws Exception {
  18. return localDate.format(formatter);
  19. }
  20. }

 每个月至少一篇博客,这个月一直在写一个新模块,比较忙,所以今天才想起来要写一篇博客,也没想到要写什么,为了不断更博客,所以就暂且随便写了这个!

 

原文链接:https://blog.csdn.net/u011174699/article/details/111998648



所属网站分类: 技术文章 > 博客

作者:lovejava

链接:http://www.javaheidong.com/blog/article/45771/c1ccdc5b606c79ca0ae0/

来源:java黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

11 0
收藏该文
已收藏

评论内容:(最多支持255个字符)