网站设计自已申请,vue响应式网站开发,姜堰网页定制,wordpress外观插件JAXB 使用记录
部分内容引自 https://blog.csdn.net/gengzhy/article/details/127564536
基础介绍
JAXBContext类#xff1a;是应用的入口#xff0c;用于管理XML/Java绑定信息 Marshaller接口#xff1a;将Java对象序列化为XML数据 Unmarshaller接口#xff1a;将XML数…JAXB 使用记录
部分内容引自 https://blog.csdn.net/gengzhy/article/details/127564536
基础介绍
JAXBContext类是应用的入口用于管理XML/Java绑定信息 Marshaller接口将Java对象序列化为XML数据 Unmarshaller接口将XML数据反序列化为Java对象 XmlRootElement将Java类或枚举类型映射到XML元素用在Java类上用于标注该类是xml的一个根节点 XmlElement将Java类的一个属性映射到与属性同名的一个XML元素。通常与XmlTransient搭配使用。 XmlTransient通常与 XmlElement 须搭配使用的。XmlElement用在属性上用于指定生成xml的节点名XmlTransient用在对应的getter方法上起到关联的作用 XmlElementWrapper 对于数组或集合即包含多个元素的成员变量生成一个包装该数组或集合的XML元素称为包装器。通常配合XmlElement一起使用XmlElementWrapper指定数组名XmlElement指定生成xml的节点名 XmlElementRef用在类属性的getter方法上即该属性是一个JavaBean并且该属性是某些子类的父类起到引用的作用。同时标注得有XmlElementRef的类属性其子类上需要使用XmlRootElement标注否则转换异常提示找不到具体的引用实现。另外转换时需要将其子类的class一起传递到JAXBContext上下文中否则也无法转换 XmlAccessorOrder控制JAXB 绑定类中属性和字段的排序 XmlType将Java类或枚举类型映射到XML模式类型 XmlAccessorType(XmlAccessType.FIELD) 控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的static、非瞬态的由XmlTransient标 注字段到XML。还有XmlAccessType.PROPERTY和XmlAccessType.NONE XmlJavaTypeAdapter使用定制的适配器即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法以序列化Java类为XML XmlAttribute将Java类的一个属性映射到与属性同名的一个XML属性
工具类
package xmlAndBean;import lombok.extern.slf4j.Slf4j;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import java.io.StringReader;
import java.io.StringWriter;/*** version : 1.0* Description : xml工具类* Date: 2023/10/9 9:03**/public class XmlBeanUtils {/*** 构造方法私有**/private XmlBeanUtils() {}public static final String ENCODING_UTF UTF-8;public static final String ENCODING_GB GB18030;/*** return java.lang.String* Description : bean转xml不含报文头GB18030编码格式* Param [obj]* Param encoding 编码格式**/public static String beanToXml(Object obj,String encoding) {String result null;try {JAXBContext context JAXBContext.newInstance(obj.getClass());Marshaller marshaller context.createMarshaller();// Marshaller.JAXB_FORMATTED_OUTPUT 决定是否在转换成xml时同时进行格式化即按标签自动换行否则即是一行的xmlmarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);// Marshaller.JAXB_ encoding xml的编码方式marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);// 去掉生成xml的默认报文头marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);StringWriter writer new StringWriter();marshaller.marshal(obj, writer);result writer.toString();} catch (Exception e) {
// log.error(bean转xml报文失败, e);}return result;}/*** return java.lang.String* 报文格式* ?xml version1.0 encodingGB18030?* ROOT* HEAD* …* /HEAD* DATA* title1 …/title1* title2 …/title2* …* /DATA* /ROOT* Description : 组装报文* Param [xmlHead, xmlData]**/public static String indentFormat(String xmlHead, String xmlData) {try {String xmlHeader ?xml version\1.0\ encoding\GB18030\?\n;StringBuilder xml new StringBuilder();xml.append(xmlHeader).append(ROOT\n).append(xmlHead).append(xmlData).append(\n/ROOT);return xml.toString();} catch (Exception e) {
// log.error(组装xml报文失败, e);return null;}}/*** xml转对象** param xml* param msgVo* param T* return*/public static T T xmlToBean(String xml, ClassT msgVo) {if (msgVo null) {return null;}try {JAXBContext context JAXBContext.newInstance(msgVo);Unmarshaller unmarshaller context.createUnmarshaller();Source source trunSource(xml);return (T) unmarshaller.unmarshal(source);} catch (Exception e) {
// log.error(xml转对象异常:, e);}return null;}/*** 忽略xml命名空间** param xmlStr* return* throws SAXException* throws ParserConfigurationException*/private static Source trunSource(String xmlStr) throws SAXException, ParserConfigurationException {StringReader reader new StringReader(xmlStr);SAXParserFactory sax SAXParserFactory.newInstance();sax.setNamespaceAware(false);XMLReader xmlReader sax.newSAXParser().getXMLReader();return new SAXSource(xmlReader, new InputSource(reader));}/*** Java Bean 转 Xml** param bean - Java Bean* param inheritClazz - Java Bean中嵌套的类且有继承关系的Java Class* return - xml*/public static String beanToXml(Object bean, String encoding,Class?... inheritClazz) {try {JAXBContext context initContext(bean.getClass(), inheritClazz);Marshaller marshaller context.createMarshaller();// 格式化xmlmarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);// Marshaller.JAXB_ encoding xml的编码方式marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);// 去掉生成xml的默认报文头marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);StringWriter writer new StringWriter();marshaller.marshal(bean, writer);return writer.toString();} catch (JAXBException e) {e.printStackTrace();}return null;}/*** Xml 转 Java Bean** param xml - xml* param beanClazz - Java Bean Class* param inheritClazz - Java Bean中嵌套的类且有继承关系的Java Class* return - bean*/public static Object xmlToBean(String xml, Class? beanClazz, Class?... inheritClazz) {try {JAXBContext context initContext(beanClazz, inheritClazz);Unmarshaller um context.createUnmarshaller();StringReader sr new StringReader(xml);return um.unmarshal(sr);} catch (JAXBException e) {e.printStackTrace();}return null;}/*** 初始化JAXBContext** param mainClazz - 序列化或反序列化Class* param inheritClazz - Java Bean中嵌套的类且有继承关系的Java Class* return - JAXBContext*/private static JAXBContext initContext(Class? mainClazz, Class?... inheritClazz) throws JAXBException {JAXBContext context;if (inheritClazz ! null) {Class?[] clazzArr new Class[inheritClazz.length 1];clazzArr[0] mainClazz;System.arraycopy(inheritClazz, 0, clazzArr, 1, clazzArr.length - 1);context JAXBContext.newInstance(clazzArr);} else {context JAXBContext.newInstance(mainClazz);}return context;}}
xml结构
结构如下
ROOT
HEAD…
/HEAD
DATAtitle1 …/title1title2 …/title2…RECORDLIST1 p_typeGtitle1 …/title1/LIST1LIST1 p_typeGtitle1 …/title1/LIST1/RECORD
/DATA
/ROOT①存在继承关系的bean转xml
基类用于统一方便向下转型
/*** version : 1.0* Description : 基类* Date: 2023/10/9 19:55**/
public class BaseDTO {
}DATA标签实体类同时继承基类
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.List;/*** version : 1.0* Description :* Date: 2023/10/9 19:55**/
Setter
Getter
ToString
XmlAccessorType(XmlAccessType.FIELD)
XmlRootElement(name DATA)
public class BookDTO extends BaseDTO{XmlElement(name name)XmlJavaTypeAdapter(CdataXmlAdapter.class)private String bookName;XmlElement(name id)private String bookId;//XmlElementWrapper(name RECORD)
// XmlElement(name LIST1)
// private ListDescDTO descDTOList;
}HEAD标签实体类
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;/*** version : 1.0* Description :* Date: 2023/10/9 19:58**/
Getter
Setter
ToString
XmlAccessorType(XmlAccessType.FIELD)
XmlRootElement(name HEAD)
public class HeadDTO {XmlElement(name SEND_NODE)private String send;XmlElement(name RECV_NODE)private String receive;
}根标签实体类 其中针对DATA标签每个接口的DATA标签可能都不相同这里使用了XmlElementRef标签结合基类BaseDTO 在使用中将接口的实体类继承BaseDTO基类并标注XmlRootElement(name “DATA”)即可实现每个接口拥有独立的对象实现bean转xml
import lombok.*;import javax.xml.bind.annotation.*;/*** version : 1.0* Description :* Date: 2023/10/9 19:55**/
Setter
Getter
ToString
NoArgsConstructor
AllArgsConstructor
XmlAccessorType(XmlAccessType.FIELD)
//XmlType(propOrder { head, data }) 这句加不加无所谓
XmlRootElement(name ROOT)
public class RootDTO {XmlElement(name HEAD)private HeadDTO head;//XmlElement(name DATA)//XmlElementRef 注解要加载对象上不能加在get方法上不然报错如下//com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 5 counts of IllegalAnnotationExceptions类的两个属性具有相同名称 headXmlElementRef(name DATA)private BaseDTO data;}测试类
public class XmlTest {public static void main(String[] args) {//继承基类BookDTO bookDTO new BookDTO();bookDTO.setBookName(name);bookDTO.setBookId(id);//HEAD标签实体类一般内容固定HeadDTO headDTO new HeadDTO();headDTO.setSend(send);headDTO.setReceive(rece);RootDTO rootDTO new RootDTO();rootDTO.setHead(headDTO);//因为BookDTO 继承基类所以此处能设置成功rootDTO.setData(bookDTO);//bean转xml需要将BookDTO.class子类传入以告知System.out.println(XmlBeanUtils.beanToXml(rootDTO,XmlBeanUtils.ENCODING_GB,BookDTO.class));//xml转beanSystem.out.println(XmlBeanUtils.xmlToBean(xml, RootDTO.class,BookDTO.class));}
}
运行结果
②存在数组的bean转xml
DATA标签实体类同时继承基类
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;import javax.xml.bind.annotation.*;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.List;/*** version : 1.0* Description :* Date: 2023/10/9 19:55**/
Setter
Getter
ToString
XmlAccessorType(XmlAccessType.FIELD)
XmlRootElement(name DATA)
public class BookDTO extends BaseDTO{XmlElement(name name)XmlJavaTypeAdapter(CdataXmlAdapter.class)private String bookName;XmlElement(name id)private String bookId;//XmlElementWrapper(name RECORD)XmlElement(name LIST1)private ListDescDTO descDTOList;
}数组实体类对象
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;import javax.xml.bind.annotation.*;/*** version : 1.0* Description :* Date: 2023/10/10 10:25**/
Getter
Setter
ToString
XmlAccessorType(XmlAccessType.FIELD)
XmlRootElement(name LIST1)
public class DescDTO{XmlAttribute(name p_type)private String pType;XmlElement(name description)private String description;
}假设在DATA标签实体类中存在数组属性则使用XmlElement(name “LIST1”)进行标注即可实现每个数组对象转换成xml时都被LIST1 /LIST1包裹 测试类
public class XmlTest {public static void main(String[] args) {BookDTO bookDTO new BookDTO();bookDTO.setBookName(name);bookDTO.setBookId(id);HeadDTO headDTO new HeadDTO();headDTO.setSend(send);headDTO.setReceive(rece);RootDTO rootDTO new RootDTO();rootDTO.setHead(headDTO);rootDTO.setData(bookDTO);DescDTO descDTO new DescDTO();//descDTO.setPType(G);descDTO.setDescription(desc11111);DescDTO descDTO1 new DescDTO();//descDTO1.setPType(G);descDTO1.setDescription(desc22222);ArrayListDescDTO descDTOS new ArrayList();descDTOS.add(descDTO);descDTOS.add(descDTO1);bookDTO.setDescDTOList(descDTOS);String xml XmlBeanUtils.beanToXml(rootDTO, XmlBeanUtils.ENCODING_GB, BookDTO.class);//bean转xmlSystem.out.println(XmlBeanUtils.beanToXml(rootDTO,XmlBeanUtils.ENCODING_GB,BookDTO.class));//xml转beanSystem.out.println(XmlBeanUtils.xmlToBean(xml, RootDTO.class,BookDTO.class));}
}运行结果 如果需要再在数组外面套一层标签则 XmlElementWrapper(name RECORD)XmlElement(name LIST1)private ListDescDTO descDTOList;运行结果
③存在数组且数组前后标签要求不一致的bean转xml
以LIST1 p_typeG标签开始以/LIST1标签结束 在数组对象中引入XmlAttribute XmlAttribute(name p_type)private String pType;测试类
//设置属性
descDTO.setPType(G);public class XmlTest {public static void main(String[] args) {BookDTO bookDTO new BookDTO();bookDTO.setBookName(name);bookDTO.setBookId(id);HeadDTO headDTO new HeadDTO();headDTO.setSend(send);headDTO.setReceive(rece);RootDTO rootDTO new RootDTO();rootDTO.setHead(headDTO);rootDTO.setData(bookDTO);DescDTO descDTO new DescDTO();descDTO.setPType(G);descDTO.setDescription(desc11111);DescDTO descDTO1 new DescDTO();descDTO1.setPType(G);descDTO1.setDescription(desc22222);ArrayListDescDTO descDTOS new ArrayList();descDTOS.add(descDTO);descDTOS.add(descDTO1);bookDTO.setDescDTOList(descDTOS);String xml XmlBeanUtils.beanToXml(rootDTO, XmlBeanUtils.ENCODING_GB, BookDTO.class);//bean转xmlSystem.out.println(XmlBeanUtils.beanToXml(rootDTO,XmlBeanUtils.ENCODING_GB,BookDTO.class));//xml转beanSystem.out.println(XmlBeanUtils.xmlToBean(xml, RootDTO.class,BookDTO.class));}
}运行结果
④针对![CDATA[文本内容]]标签
import javax.xml.bind.annotation.adapters.XmlAdapter;/*** version : 1.0* Description : ![CDATA]* Date: 2023/10/8 19:03**/
public class CdataXmlAdapter extends XmlAdapterString, String {public CdataXmlAdapter() {}public String marshal(String arg0) throws Exception {return ![CDATA[ arg0 ]];}public String unmarshal(String arg0) throws Exception {return arg0;}
}使用XmlJavaTypeAdapter注解在需要的字段上 XmlElement(name name)XmlJavaTypeAdapter(CdataXmlAdapter.class)private String bookName;运行结果