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

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 convertToJavaBean(String xml, Class 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 {

    /**
     * 
     *         
     *         
     */
    @XmlElement(name = "PatPara",required =true)
    private String patPara;

    @XmlElementWrapper(name ="FlightSegments",required =true )
    @XmlElement(name ="FlightSegment",required =true )
    private List flightSegments;

    /**
     * 
     */
    @XmlElement(name = "PNR",nillable = true,required = true)
    private String pnr;

    /**
     * 
     */
    @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;
    /**
     * 
     */
    @XmlElement(name = "AllowUncertainPrice",nillable = true,required = true)
   private String allowUncertainPrice;


}

其中@XmlElement注解中的参数,那么是元素标签名例如第一个属性对应的xml标签为,required=true,表示这个元素标签是必须的,即使该标签元素没有值,也要转换显示出来,例如这个,是没有给该标签元素赋值的,但是仍然会显示出来,如果没有加required=true,那么该参数值required默认为false,当pnr=""或pnr=null时,也就是没有赋予有效值的时候,该元素不转换显示出来,那么最后的xml文档中就没有了该元素,nillable=true,表示该元素可以为null,就是当该java类的对应属性如pnr=null时,也就是没有对该属性初始化赋值,这时候,该属性要转换成的对应的xml文档元素也是null,此时转换为xml标签元素会出错,加上这个就不会报错了,同时显示格式会是最下边那张截图里的那样的元素显示方式,如: 

对于List性质的属性,也就是在xml文档会多次出现相同的标签元素的,list属性对应的xml注解就是@XmlElementWrapper,然后下边加的注解就是会出现多个相同标签元素的标签名,还是用@XmlElement

由于list集合中包含的也是对象,所以,对象也需要加xml注解,来表示xml中所在位置

例如

@XmlElementWrapper(name ="FlightSegments",required =true )
    @XmlElement(name ="FlightSegment",required =true )
    private List 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格式传递过来的)

JAXB处理java对象与xml格式之间的转换_第1张图片

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

例如:



    
        
            SC
            9009
            CAN
            LYI
            2020-12-31
            V
        
    

这个标签需要一个日期格式的值,并且是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 {
    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);
    }
}

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

 

你可能感兴趣的:(数据格式,java基础,JavaWeb,xml,jaxb,javaee)