网上这方面资料不好找,所以就简要记一下。
参考资料:
JAXB常用注解讲解(超详细)
玩转Java对象和XML相互转换
下面以微信支付V2的异步通知XML转对象为例:
首先定义实体类:
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(
name = "xml"
)
@XmlAccessorType(XmlAccessType.FIELD)
public class WxPayAsyncResponse {
@XmlElement(
name = "return_code"
)
private String returnCode;
@XmlElement(
name = "return_msg",
required = false
)
private String returnMsg;
@XmlElement(
name = "appid",
required = false
)
private String appid;
@XmlElement(
name = "mch_id",
required = false
)
private String mchId;
@XmlElement(
name = "device_info",
required = false
)
private String deviceInfo;
@XmlElement(
name = "nonce_str",
required = false
)
private String nonceStr;
@XmlElement(
name = "sign",
required = false
)
private String sign;
@XmlElement(
name = "result_code",
required = false
)
private String resultCode;
@XmlElement(
name = "err_code",
required = false
)
private String errCode;
@XmlElement(
name = "err_code_des",
required = false
)
private String errCodeDes;
@XmlElement(
name = "openid",
required = false
)
private String openid;
@XmlElement(
name = "is_subscribe",
required = false
)
private String isSubscribe;
@XmlElement(
name = "trade_type",
required = false
)
private String tradeType;
@XmlElement(
name = "bank_type",
required = false
)
private String bankType;
@XmlElement(
name = "total_fee",
required = false
)
private Integer totalFee;
@XmlElement(
name = "fee_type",
required = false
)
private String feeType;
@XmlElement(
name = "cash_fee",
required = false
)
private String cashFee;
@XmlElement(
name = "cash_fee_type",
required = false
)
private String cashFeeType;
@XmlElement(
name = "coupon_fee",
required = false
)
private String couponFee;
@XmlElement(
name = "coupon_count",
required = false
)
private String couponCount;
@XmlElement(
name = "transaction_id",
required = false
)
private String transactionId;
@XmlElement(
name = "out_trade_no",
required = false
)
private String outTradeNo;
@XmlElement(
name = "attach",
required = false
)
private String attach;
@XmlElement(
name = "time_end",
required = false
)
private String timeEnd;
@XmlElement(
name = "mweb_url",
required = false
)
private String mwebUrl;
@XmlElement(
name = "settlement_total_fee",
required = false
)
private Integer settlementTotalFee;
@XmlElement(
name = "coupon_type",
required = false
)
private String couponType;
public WxPayAsyncResponse() {
}
......省略Getter/Setter.......
}
其次是xml对象互转的工具类,第二个参考资料里面提供的:
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.*;
/**
* xml工具类
* https://blog.csdn.net/songdeitao/article/details/17304395
*
* @author yz
* @className XmlUtil
* @date 2020/11/26 17:42
*/
public class XmlUtil {
/**
* 将对象直接转换成String类型的 XML输出
*
* @param obj
* @return
*/
public static String convertToXml(Object obj) {
// 创建输出流
StringWriter sw = new StringWriter();
try {
// 利用jdk中自带的转换类实现
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// 格式化xml输出的格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
// 将对象转换成输出流形式的xml
marshaller.marshal(obj, sw);
} catch (JAXBException e) {
e.printStackTrace();
}
return sw.toString();
}
/**
* 将对象根据路径转换成xml文件
*
* @param obj
* @param path
* @return
*/
public static void convertToXml(Object obj, String path) {
try {
// 利用jdk中自带的转换类实现
JAXBContext context = JAXBContext.newInstance(obj.getClass());
Marshaller marshaller = context.createMarshaller();
// 格式化xml输出的格式
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
Boolean.TRUE);
// 将对象转换成输出流形式的xml
// 创建输出流
FileWriter fw = null;
try {
fw = new FileWriter(path);
} catch (IOException e) {
e.printStackTrace();
}
marshaller.marshal(obj, fw);
} catch (JAXBException e) {
e.printStackTrace();
}
}
/**
* 将String类型的xml转换成对象
*/
public static Object convertXmlStrToObject(Class clazz, String xmlStr) {
Object xmlObject = null;
try {
JAXBContext context = JAXBContext.newInstance(clazz);
// 进行将Xml转成对象的核心接口
Unmarshaller unmarshaller = context.createUnmarshaller();
StringReader sr = new StringReader(xmlStr);
xmlObject = unmarshaller.unmarshal(sr);
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlObject;
}
/**
* 将file类型的xml转换成对象
*/
public static Object convertXmlFileToObject(Class clazz, String xmlPath) {
Object xmlObject = null;
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
FileReader fr = null;
try {
fr = new FileReader(xmlPath);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
xmlObject = unmarshaller.unmarshal(fr);
} catch (JAXBException e) {
e.printStackTrace();
}
return xmlObject;
}
}
最后就直接用了:
WxPayAsyncResponse asyncResponse = (WxPayAsyncResponse) XmlUtil.convertXmlStrToObject(WxPayAsyncResponse.class, notifyData);
需要注意的是实体类中的@XmlAccessorType这个注解,具体用法参见参考资料一。