JAXBContext 为非根节点添加多个属性或多个子节点添加属性
效果如下:
多个子节点添加属性
同一节点添加多个属性
@XmlValue 注解同一个类只能出现一次
@XmlJavaTypeAdapter(CdataXmlAdapter.class) 注解处理长字符串,转xml时添加 <![CDATA[ ]]>,CdataXmlAdapter为自定义类,具体见:
JAXBContext 实现 XML与bean互相转换
1、多个子节点添加属性
生成xml 如下
<?xml version="1.0" encoding="UTF-8"?>
<httpPost>
<bSwitch type="true">boolean</bSwitch>
<protocolType><![CDATA[123]]></protocolType>
<serverIp><![CDATA[192.168.1.56]]></serverIp>
<serverPort name="tome" type="int32">
<serverPort>123</serverPort>
</serverPort>
<keepaliveTimeval type="1111">int32</keepaliveTimeval>
<onlineStatus type="false3">boolean</onlineStatus>
</httpPost>
public static void main(String[] args) {
IotTvtHttpPostDataParam httpPost = new IotTvtHttpPostDataParam();
httpPost.setProtocolType("123");
httpPost.setServerIp("192.168.1.56");
IotTvtbSwitchData switchData = new IotTvtbSwitchData();
switchData.setBSwitch("true");
switchData.setValue("boolean");
httpPost.setBSwitch(switchData);
IotServerPortData serverPortData = new IotServerPortData();
serverPortData.setServerPort(123);
serverPortData.setType("int32");
serverPortData.setName("tome");
httpPost.setServerPort(serverPortData);
IotKeepaliveTimevalData keepaliveTimevalData = new IotKeepaliveTimevalData();
keepaliveTimevalData.setKeepaliveTimeval(1111);
keepaliveTimevalData.setValue("int32");
httpPost.setKeepaliveTimeval(keepaliveTimevalData);
IotOnlineStatusData onlineStatusData = new IotOnlineStatusData();
onlineStatusData.setOnlineStatus("false3");
onlineStatusData.setValue("boolean");
httpPost.setOnlineStatus(onlineStatusData);
//生成XML
String toXml = XmlUtil.toXml(httpPost);
System.out.println();
}
bean 结构如下:
IotTvtHttpPostDataParam
import lombok.Data;
import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.io.Serializable;
@Data
@XmlRootElement(name = "httpPost")
@XmlAccessorType(XmlAccessType.FIELD)
public class IotTvtHttpPostDataParam implements Serializable {
@XmlElement
private IotTvtbSwitchData bSwitch;
@XmlJavaTypeAdapter(CdataXmlAdapter.class)
private String protocolType;
@XmlJavaTypeAdapter(CdataXmlAdapter.class)
private String serverIp;
@XmlElement
private IotServerPortData serverPort;
@XmlElement
private IotKeepaliveTimevalData keepaliveTimeval;
@XmlElement
private IotOnlineStatusData onlineStatus;
}
IotTvtbSwitchData
import lombok.Data;
import javax.xml.bind.annotation.*;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class IotTvtbSwitchData {
@XmlAttribute(name = "type")
private String bSwitch;
@XmlValue
private String value;
}
IotServerPortData
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class IotServerPortData {
private int serverPort;
@XmlAttribute
private String name;
@XmlAttribute
private String type;
}
IotKeepaliveTimevalData
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class IotKeepaliveTimevalData {
@XmlAttribute(name = "type")
private int keepaliveTimeval;
@XmlValue
private String value;
}
IotOnlineStatusData
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class IotOnlineStatusData {
@XmlAttribute(name = "type")
private String onlineStatus;
@XmlValue
private String value;
}
XmlUtil
import cn.hutool.json.JSONUtil;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Proxy;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class XmlUtil {
private static final Logger log = LoggerFactory.getLogger(XmlUtil.class);
public XmlUtil() {
}
public static <T> T toBean(Class<T> c, String xmlStr) {
try {
Reader reader = new StringReader(xmlStr);
Throwable var3 = null;
Object var9;
try {
JAXBContext jaxbContext = JAXBContext.newInstance(new Class[]{c});
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
SAXParserFactory sax = SAXParserFactory.newInstance();
sax.setNamespaceAware(false);
XMLReader xmlReader = sax.newSAXParser().getXMLReader();
Source source = new SAXSource(xmlReader, new InputSource(reader));
var9 = unmarshaller.unmarshal(source);
} catch (Throwable var19) {
var3 = var19;
throw var19;
} finally {
if (reader != null) {
if (var3 != null) {
try {
reader.close();
} catch (Throwable var18) {
var3.addSuppressed(var18);
}
} else {
reader.close();
}
}
}
return var9;
} catch (Exception var21) {
log.error("toBean Exception: {}", xmlStr, var21);
return null;
}
}
public static String toXml(Object obj) {
try {
StringWriter writer = new StringWriter();
XMLStreamWriter streamWriter = XMLOutputFactory.newInstance().createXMLStreamWriter(writer);
XMLStreamWriter cdataStreamWriter = (XMLStreamWriter)Proxy.newProxyInstance(streamWriter.getClass().getClassLoader(), streamWriter.getClass().getInterfaces(), new CdataHandler(streamWriter));
JAXBContext jc = JAXBContext.newInstance(new Class[]{obj.getClass()});
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty("jaxb.encoding", "UTF-8");
marshaller.marshal(obj, cdataStreamWriter);
return indentFormat(writer.toString());
} catch (Exception var6) {
log.error("toXml Exception: {}", JSONUtil.toJsonStr(obj), var6);
return null;
}
}
private static String indentFormat(String xml) {
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty("indent", "yes");
transformer.setOutputProperty("omit-xml-declaration", "yes");
transformer.setOutputProperty("encoding", "UTF-8");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
StringWriter formattedStringWriter = new StringWriter();
transformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(formattedStringWriter));
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + formattedStringWriter;
} catch (Exception var4) {
log.error("indentFormat Exception", var4);
return "";
}
}
}
2、同一节点添加多个属性
以上面示例为基础 进行了部分修改
IotServerPortData类
xml效果如下:
生成的 XML
<?xml version="1.0" encoding="UTF-8"?>
<httpPost>
<bSwitch type="true">boolean</bSwitch>
<protocolType><![CDATA[123]]></protocolType>
<serverIp><![CDATA[192.168.1.56]]></serverIp>
<serverPort title="123" name="tome" type="int32">测试</serverPort>
<keepaliveTimeval type="1111">int32</keepaliveTimeval>
<onlineStatus type="false3">boolean</onlineStatus>
</httpPost>
IotServerPortData 修改后
import lombok.Data;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlValue;
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class IotServerPortData {
@XmlAttribute(name = "title")
private int serverPort;
@XmlAttribute
private String name;
@XmlAttribute
private String type;
@XmlValue
private String value;
}
main 方法中 IotServerPortData 赋值
IotServerPortData serverPortData = new IotServerPortData();
serverPortData.setServerPort(123);
serverPortData.setType("int32");
serverPortData.setName("tome");
serverPortData.setValue("测试");
httpPost.setServerPort(serverPortData);