感觉比 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());
}
}
/* 按照下面的示例作了一个总结,文字结合下面的代码更容易理解
总结一下规则:
defer里面的变量必须与函数定义的返回值变量是同一个变量才会在最后的时候return defer自执行函数操作后的结果。
不满足这个条件,return的结果就不是defer自执行函数操作后的结果。return变量的类型要和函数