网站开发怎么入账,网站热区图,苏州网站建设运营推广,国外做网站公司能赚钱Spring boot项目实现java bean和xml互转 项目场景#xff1a;互转方法使用jackson进行互转使用jaxws进行xml与bean的互转 搞定收工#xff01; 项目场景#xff1a;
工作中需要给下游第三方收费系统做数据挡板#xff0c;由于下游系统使用的是soap webservice,里面涉及各种… Spring boot项目实现java bean和xml互转 项目场景互转方法使用jackson进行互转使用jaxws进行xml与bean的互转 搞定收工 项目场景
工作中需要给下游第三方收费系统做数据挡板由于下游系统使用的是soap webservice,里面涉及各种xml跟bean的互转在此介绍一下使用的方法。 基于springboot搭建webservice的过程将会在下篇博客介绍 互转方法
这里介绍两种方法.
使用jackson进行互转Spring boot项目自带的json和bean的互转的框架他其实还有xml与bean的互转。使用jaxws进行xml与bean的互转 使用jackson进行互转 因为Spring Boot 项目其他依赖基本上都会引入只是缺少一个依赖com.fasterxml.jackson.dataformat:jackson-dataformat-xml,所以只需要引入这一个依赖即可。 gradle引入
implementation(com.fasterxml.jackson.dataformat:jackson-dataformat-xml)maven 引入 dependencygroupIdcom.fasterxml.jackson.dataformat/groupIdartifactIdjackson-dataformat-xml/artifactIdversion2.13.5/version/dependency可以做成一个通用的XMLUtils工具类,代码如下 public static String javaBean2Xml(Object javaBean) throws JsonProcessingException {XmlMapper xmlMapper new XmlMapper();xmlMapper.setDefaultUseWrapper(false);//字段为null就自动忽略不再序列化xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);//XML标签名:使用骆驼命名的属性名xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);//设置转换模式就是根据getter、setter方法,设置为第一个字母小写这种xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);return xmlMapper.writeValueAsString(javaBean);}public static T T Xml2javaBean(String javaBean, ClassT tClass) throws JsonProcessingException {XmlMapper xmlMapper new XmlMapper();xmlMapper.setDefaultUseWrapper(false);//字段为null自动忽略不再序列化xmlMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);//XML标签名:使用骆驼命名的属性名xmlMapper.setPropertyNamingStrategy(PropertyNamingStrategies.UPPER_CAMEL_CASE);//设置转换模式就是根据getter、setter方法,设置为第一个字母小写这种xmlMapper.enable(MapperFeature.USE_STD_BEAN_NAMING);return xmlMapper.readValue(javaBean, tClass);}POJO类后续都会用这个做例子
public class Student {private String name;private String teacher;private Integer age;....省略构造函数和getter和setter
}测试案例
public static void main(String[] args) throws JsonProcessingException {Student student new Student(张三,张老师, 26);String s XMLUtils.javaBean2Xml(student);System.out.println(s);System.out.println(XMLUtils.Xml2javaBean(s, Student.class));
}结果
可能会出现的bug 在使用jackson去进行转换的时候POJO类不管几个构造函数一定要有无参构造否则就会报错。 com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of Student (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator) 如果想给POJO的属性的XML起个别名怎么办jackson是提供了相关的注解。 JacksonXmlRootElement namespace属性用于指定XML根元素命名空间的名称。 localname属性用于指定XML根元素节点标签的名称。JacksonXmlProperty namespace和localname属性用于指定XML命名空间的名称isAttribute指定该属 性作为XML的属性还是作为子标签.JacksonXmlText注解将属性直接作为未被标签包裹的普通文本。JacksonXmlCData将属性包裹在CDATA标签中。集合元素的映射 JacksonXmlElementWrapper可以将列表数据转为XML节点。 useWrapping属性设置是否设置外围标签名默认true 其他的可以自己尝试下如果是List的集合的是以一对多的一对应的一里面定义了XML节点就以一里面的定义为主。 补充完整的依赖和Spring Boot已经引入的依赖。 完整依赖dependencygroupIdcom.fasterxml.jackson.dataformat/groupIdartifactIdjackson-dataformat-xml/artifactIdversion2.13.5/version
/dependency
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-databind/artifactIdversion2.13.5/version
/dependency
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-core/artifactIdversion2.13.5/version
/dependency
dependencygroupIdcom.fasterxml.jackson.core/groupIdartifactIdjackson-annotations/artifactIdversion2.13.5/version
/dependencySpring Boot已经引入的依赖以2.6.12为例 使用jaxws进行xml与bean的互转 使用起来基本是跟jackson差不多的。好处就是jdk自己就有提供不需要引入额外的工具包主要是使用javax下的 JAXBContext 接口利用Marshaller 和Unmarshaller接口来进行xml与bean的互转。 但是需要注意的是 必须要提供无参构造器否则会报错com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Student没有无参数默认构造器。必须在类上提供javax.xml.bind.annotation.XmlRootElement否则会报错javax.xml.bind.MarshalException -with linked exception: [com.sun.istack.SAXException2: 由于类型 “Student” 缺少 XmlRootElement 注释, 无法将该类型编集为元素]如果不提供javax.xml.bind.annotation.XmlElement注解那么所产生的XML节点均为属性值就是小写。javax.xml.bind.annotation.XmlElement定义的值不能跟getter方法一起出现否则会报错com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions 类的两个属性具有相同名称 “name” 老规矩工具类 public static String beanToXml (Object obj, Class? zlass) throws JAXBException {JAXBContext context JAXBContext.newInstance(zlass);Marshaller marshaller context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.setProperty(Marshaller.JAXB_ENCODING, GBK);marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);StringWriter writer new StringWriter();marshaller.marshal(obj,writer);return writer.toString();}public static T T xmlToBean (String xml, ClassT zlass) throws JAXBException {JAXBContext context JAXBContext.newInstance(zlass);Unmarshaller unmarshaller context.createUnmarshaller();Object object unmarshaller.unmarshal(new StringReader(xml));return (T) object;}Marshaller 接口中还定义了5个属性分别是 JAXB_ENCODING 这个属性是设置编码集 marshaller.setProperty(Marshaller.JAXB_ENCODING, “GBK”);JAXB_FORMATTED_OUTPUT 这个属性是是否格式化生成的xml串 true-格式化false-不格式化 marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);JAXB_SCHEMA_LOCATION 指定xsi:schemaLocation,它定义了XML Namespace和对应的XSDXml Schema Definition文档的位置的关系。它的值由一个或多个URI引用对组成两个URI之间以空白符分隔空格和换行均可。第一个URI是定义的XML Namespace的值第二个URI给出Schema文档的位置Schema处理器将从这个位置读取Schema文档该文档的targetNamespace必须与第一个URI相匹配。 marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, “xxx.xxx.xxx”);JAXB_NO_NAMESPACE_SCHEMA_LOCATION 如果没有Namespeace但是需要使用Schema就需要用到JAXB_NO_NAMESPACE_SCHEMA_LOCATION,它可以指定将放置在已编组 XML 输出中的 xsi:noNamespaceSchemaLocation 属性值 marshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, “xxx.xxx.xxx”);JAXB_FRAGMENT 是否省略xml头信息true-省略false-不省略 marshaller.setProperty(Marshaller.JAXB_FRAGMENT, false); 代码
public static void main(String[] args) throws Exception {Student student new Student(张三,张老师, 26);String s XMLUtils.beanToXml(student, Student.class);System.out.println(s);System.out.println(XMLUtils.xmlToBean(s, Student.class));
}测试 最后补充几个注解 XmlRootElement 类级别的注解,这个注解为根节点的注解加在类上面而且为必要的注解如果没有此注解执行beanToXml方法时将会报异常。这个根节点默认名字为类名但是可以设置name属性来修改根节点名字。namespace属性可以用于指定生成的元素所属的命名空间。XmlElement 字段方法级别的注解将java类的属性映射为xml的一个结点。一般使用在属性上或者get方法上其中常用的属性有name、nillable、namespace、defaultValue。name可以设置结点的名称nillable 指定文本是否可以为空true-可以为空false-不可以为空默认为false如果设置为true则该字段为空是这个结点也会生成但是值为空如果是指为false则该结点不生成namespace属性可以用于指定生成的元素所属的命名空间defaultValue 可以设置该结点的默认文本。XmlTransient 类字段方法级别的注解。当添加这个注解后这个属性或者类将不进行映射。需要注意的是该注解与所有其他JAXB注解相互排斥.XmlAccessorType 类级别注解其中有一个value属性值为XmlAccessType的枚举类。 1.XmlAccessType.PROPERTY 加这个value表示会将所有拥有get方法和set方法的属性必须2个方法都有否则不映射映射成xml除非加入XmlTransient则不会映射如果没有get/set方法则需要再属性上加上XmlElement。 2.XmlAccessType.FIELD 这个属性是将类中非静态的属性都映射到xml中并且不需要加get/set方法 3.XmlAccessType.PUBLIC_MEMBER 这个属性值是XmlAccessorType的默认默认值它会将属性为public的属性或者get/set方法同时为public的属性映射成xml。 4.XmlAccessType.NONE 这个属性表示任何属性都不会被映射到xml中除非使用其他注解如XmlElementXmlAccessorOrder 类级别的注解。控制生成属性映射xml结点的顺序。其中有一个value属性可以设置排序方式XmlAccessOrder.ALPHABETICAL 为按照字母顺序进行排序 XmlAccessOrder.UNDEFINED按照属性顺序进行排序默认为XmlAccessOrder.UNDEFINEDXmlJavaTypeAdapter 这个注解主要是解决一些数据格式化问题的比如时间格式化。XmlElementWrapper 这个注解是加在集合上面的XmlAttribute 这个注解会将属性变为上一个结点的属性XmlType 类级别的注解这个注解可以自定义排序使用propOrder 属性。 搞定收工