15课:关于自定义生成xml和解析xml的代码内容;

简介

现在的项目中请求和响应大多数使用的都是json个数的;但是有些需要调用三方的接口依然使用的是通过xml来接受参数以及响应结果的;就需要我们根据三方的要求生成指定格式的xml字符串,以及根据返回的xml格式字符串解析成map格式(或者对应的实体类)
项目demo下载

项目结构

在这里插入图片描述

生成的xml格式的样例

生成的自定义的xml格式的

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<RootElement xmlns="https://www.baidu.com/">
    <version>1.0</version>
    <User>
        <userName>小康康</userName>
        <mobile>13051999560</mobile>
        <age>10</age>
        <money>200.22</money>
        <birthday>2020-08-28T09:57:51.329+08:00</birthday>
        <addressModel>
            <address>北京市通州区</address>
            <postCode>100010</postCode>
        </addressModel>
    </User>
    <Order>
        <orderId>20200811</orderId>
        <orderName>淘宝商品</orderName>
    </Order>
    <Order>
        <orderId>20200812</orderId>
        <orderName>京东商品</orderName>
    </Order>
    <Msg>
        <retCode>10000</retCode>
        <retInfo>执行成功</retInfo>
    </Msg>
</RootElement>

代码实现内容;

1.pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.khy.boot</groupId>
  <artifactId>boot-xml</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
  <!-- xml解析和设置的内容; -->
  <parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.4.RELEASE</version>
	</parent>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
		<!--含有多个main 需要指定某一个启动class-->
		<start-class>com.khy.SpringBootMainApplication</start-class>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.4</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.6</version>
		</dependency>
		<dependency>
			<groupId>org.jdom</groupId>
			<artifactId>jdom</artifactId>
			<version>1.1</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

主要需要引入的是

在这里插入图片描述

2.package-info.java

生成的xml根节点里面的xmlns 地址里面的链接内容;来自对于entity 包下面的package-info.java里面设置的;
@XmlSchema(namespace="https://www.baidu.com/", elementFormDefault= XmlNsForm.QUALIFIED)
package com.khy.entity;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

3.根节点里面的属性配置

package com.khy.entity;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * xml格式最外层的结构内容
 * @author khy
 * @createTime 2020年8月27日下午3:36:38
 */
@XmlRootElement(name = "RootElement")//指定xml最外层 root节点的名称
@XmlAccessorType(XmlAccessType.FIELD)
public class RootElement {
    private String version;//root节点的version字段;
    
    @XmlElement(name = "User")//标识root节点的子节点名称;
    private UserModel userModel;
    
    @XmlElement(name = "Order")//标识root节点的子节点名称;
    private List<OrderModel> orders;
    
    @XmlElement(name = "Msg")//标识root节点的子节点名称;
    private MsgModel msgModel;
	 get/set省略/
}

@XmlRootElement 注解标识根节点的名称是;
@XmlElement标识根节点下面的属性名称是
当前案例中,我们的根节点下面有一个User节点以及一个List<Order>节点和一个Msg节点;
对应的User节点下面还有addressModel(属性如果不通过@XmlElement指定节点名称默认去字段属性)
其中对于的子节点中的属性配置

在这里插入图片描述

3.main入口方法

public static void main(String[] args) {
		RootElement root = new RootElement();
		root.setVersion("1.0");
		UserModel user = new UserModel();
		root.setUserModel(user);
		user.setUserName("小康康");
		user.setMobile("13051999560");
		user.setMoney(new BigDecimal("200.22"));
		user.setAge(10);
		user.setBirthday(new Date());
		user.setAddressModel(new AddressModel("北京市通州区", "100010"));
		List<OrderModel>orders = new ArrayList<OrderModel>(){{
			add(new OrderModel("20200811", "淘宝商品"));
			add(new OrderModel("20200812", "京东商品"));
		}};
		root.setOrders(orders);
		root.setMsgModel(new MsgModel("10000","执行成功"));
		System.out.println(JSON.toJSONString(root));
		String convertToXml = XMLUtil.convertToXml(root);
		//这里打印的就是我们组装的xml格式的报文内容
		System.out.println(convertToXml);
		
		//解析对于的xml内容;
		Element element = ParseXMLUtil.parseXML(convertToXml);
		HashMap<String, Object> toMap = ParseXMLUtil.xmlToMap(element, "User", "Order");//设置我们需要解析的节点;
		System.out.println(JSON.toJSONString(toMap));
		
		
		HashMap<String, Object> xmlToMap = ParseXMLUtil.xmlToMap(element);
		System.out.println(JSON.toJSONString(xmlToMap));
	}
然后看一下代码中的打印的结果RootElement 转成json格式的数据的样式

在这里插入图片描述

然后看一下生成的xml 的样式内容

在这里插入图片描述

	节点的名称不一样是因为model属性和@XmlElement 注解里面的设置的name不一样导致的;我们可以在RootElement 中将子节点属性名称@XmlElement注解给去掉这样的话就是一致的信息

然后看一下我们转成和实体类转成json相同目录结构的 map打印的结果

在这里插入图片描述

转成对应的map结构的数据内容;由于我们的key选择的是节点的名称所以导致的map打印成json格式和原来的RootElement对于转成json属性值不一样;

所以如果属性值是一样的可以转成map结构之后然后转成json字符串,在解析成我们指定的目标的对象内容;

4. XMLUtil.java

将目标对象转成xml格式的字符串输出

 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();  
    }  

5.ParseXMLUtil.java 解析xml转成map

/**
	 * 解析条件设置(如果root节点下的的子节点还有)
	 * @author  khy
	 * @createTime 2020年8月27日下午5:20:37
	 * @param root
	 * @return
	 */
	public static HashMap<String,Object> xmlToMap(Element root){
		if(null == root){
			return null;
		}
		Element child=null;			//定义一个Element元素对象
		HashMap<String,Object> rootMap=new HashMap<String,Object>(); //初始化HashMap,用来保存得到的数据
		//下面开始迭代循环
		for (Iterator childs1= root.getChildren().iterator();childs1.hasNext();) {
			child=(Element)childs1.next(); //获取每一个子元素
			parseXml(child,rootMap);
		}
		//循环结束
		return rootMap;
	}

	/**
	 * 通过递归解析对于的xml节点内容
	 * @author  khy
	 * @createTime 2020年8月28日上午10:00:43
	 * @param child
	 * @param map
	 */
	private static void parseXml(Element child, Map<String, Object> map) {
		String childName = child.getName();  //得到该节点的名称
		boolean hasChild = hasChild(child);
		if(hasChild){//说明下面没有子节点内容;
			map.put(childName, child.getValue());  //将子元素保存到HashMap中
		}else{
			Object object = map.get(childName);
			if(null == object){//标识没有设置过(则是map格式的)
				Map<String,Object>childMap = new HashMap<String, Object>();
				List children = child.getChildren();
				for (Object obj : children) {
					Element element = (Element) obj;
					parseXml(element, childMap);
				}
				map.put(childName, childMap);
			}else{//标识不等于空
				if(object instanceof Map){
					//标识第一次进来的设置的是map 然后需要将map转成List<Map>格式的;
					List<Map<String,Object>>childList = new ArrayList<Map<String,Object>>();
					childList.add((Map<String, Object>) object);
					Map<String,Object>childMap = new HashMap<String, Object>();
					List children = child.getChildren();
					for (Object obj : children) {
						Element element = (Element) obj;
						parseXml(element, childMap);
					}
					childList.add(childMap);
					map.put(childName, childList);
				}else if(object instanceof List){
					Map<String,Object>childMap = new HashMap<String, Object>();
					List children = child.getChildren();
					for (Object obj : children) {
						Element element = (Element) obj;
						parseXml(element, childMap);
					}
					List<Map<String,Object>>childList = (List<Map<String, Object>>) object;
					childList.add(childMap);
					map.put(childName, childList);
				}
			}
		}
	}

	/**
	 * 是否有子节点
	 * @author  khy
	 * @createTime 2020年8月27日下午5:31:00
	 * @param child
	 * @return
	 */
	private static boolean hasChild(Element child) {
		List children = child.getChildren();
		if(CollectionUtils.isEmpty(children)){
			return true;
		}
		return false;
	}

代码重要通过 jdk中自带的@Xml XXX注解来实现的功能内容;

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值