Xml Entity 实体互转(JAXB)

感觉比 xStream 操作起来复杂些 Xml Entity 实体互转(XStream)。但学习成本低些,不需要引用第三方依赖包

需要注意的是 实体中如果加了 getXX 需要在上面加上 @XmlTransient 否则会报“类的两个属性具有相同的名称

Intellij idea getter setter 模板设置

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.Serializable;
import java.util.Date;

/**
 * 患者基本信息
 */
@XmlRootElement(name="PatientInfo")//表示根元素
public class PatientInfoVo implements Serializable {

    /**
     * 患者ID 没加 @XmlElement 不会生成 xml
     */
    private String patientId;


    /**
     * 患者信息
     */
    @XmlElement(name = "PAT_NAME")
    private String patientName;


    /**
     * 患者性别
     */
    @XmlElement(name = "PatientGender")
    private Boolean gender;

    /**
     * 出生日期
     */
    @XmlElement(name = "DATE_BIRTH")
    @XmlJavaTypeAdapter(DateXmlAdapter.class)
    private Date patientBirthdate;

    /**
     *
     */
    @XmlElement(name = "MedicalType")
    private Integer medicalType;

    
    public String getPatientId() {
        return patientId;
    }

    public void setPatientId(String patientId) {
        this.patientId = patientId;
    }

    @XmlTransient
    public String getPatientName() {
        return patientName;
    }

    public void setPatientName(String patientName) {
        this.patientName = patientName;
    }

    @XmlTransient
    public Boolean getGender() {
        return gender;
    }

    public void setGender(Boolean gender) {
        this.gender = gender;
    }

    @XmlTransient
    public Date getPatientBirthdate() {
        return patientBirthdate;
    }

    public void setPatientBirthdate(Date patientBirthdate) {
        this.patientBirthdate = patientBirthdate;
    }

    @XmlTransient
    public Integer getMedicalType() {
        return medicalType;
    }

    public void setMedicalType(Integer medicalType) {
        this.medicalType = medicalType;
    }

    @Override
    public String toString() {
        return "PatientInfoVo{" +
                "patientId='" + patientId + '\'' +
                ", patientName='" + patientName + '\'' +
                ", gender=" + gender +
                ", patientBirthdate=" + patientBirthdate +
                ", medicalType=" + medicalType +
                '}';
    }

}

 DateXmlAdapter

import javax.xml.bind.annotation.adapters.XmlAdapter;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 日期格式化
 */
public class DateXmlAdapter extends XmlAdapter<String, Date> {
    private  final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public Date unmarshal(String date) throws Exception {
        return SDF.parse(date);
    }

    @Override
    public String marshal(Date date) throws Exception {
        return SDF.format(date);
    }
}

Test.java

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.test.context.SpringBootTest;

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;
import java.util.Date;


@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class XmlTests {
    Logger logger = LoggerFactory.getLogger(this.getClass());


    /**
     * 玩得不熟,没有拼字符串来得直接
     */
    @Test
    void entityToxmlTest() {
        PatientInfoVo info = new PatientInfoVo();
        info.setPatientId("这个没添加注解");
        info.setPatientName("张三");
        info.setGender(false);
        info.setMedicalType(1); //TODO 待转成应对的汉字
        info.setPatientBirthdate(new Date());

        StringWriter sw = new StringWriter();
        try {
            //根据Person类生成上下文对象
            JAXBContext jc = JAXBContext.newInstance(PatientInfoVo.class);
            //从上下文中获取Marshaller对象,用作将bean编组(转换)为xml
            Marshaller ma = jc.createMarshaller();
            //以下是为生成xml做的一些配置
            //格式化输出,即按标签自动换行,否则就是一行输出
            ma.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            //设置编码(默认编码就是utf-8)
            ma.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            //是否省略xml头信息,默认不省略(false)
            ma.setProperty(Marshaller.JAXB_FRAGMENT, true);
            //编组
            ma.marshal(info, sw);
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        logger.info("\r\n" + sw.toString());
    }


    /**
     * 反转还行,挺方便,复杂的结构可以参考一些其它资料
     */
    @Test
    void xmlToEntityTest() throws JAXBException {
        String xml = "<PatientInfo>\n" +
                "    <PAT_NAME>张三</PAT_NAME>\n" +
                "    <PatientGender>false</PatientGender>\n" +
                "    <DATE_BIRTH>2021-10-22 12:39:20</DATE_BIRTH>\n" +
                "    <MedicalType>1</MedicalType>\n" +
                "</PatientInfo>\n";
        JAXBContext jc = JAXBContext.newInstance(PatientInfoVo.class);
        //从上下文中获取Marshaller对象,用作将bean编组(转换)为xml
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        PatientInfoVo user = (PatientInfoVo) unmarshaller.unmarshal(new StringReader(xml));
        logger.info(user.toString());
    }
}

 

posted @ 2021-10-22 13:01  VipSoft  阅读(356)  评论(0编辑  收藏  举报