zl程序教程

您现在的位置是:首页 >  Java

当前栏目

Xml转Java实体类对象 xml转Javabena 对象 且多级嵌套 复杂嵌套

2023-04-18 12:37:19 时间

最近在做企微开发,遇到了一个比较复杂的xml然后要去我将xml转成实体类
xml如下

<xml>
	<ToUserName><![CDATA[toUser]]></ToUserName>
	<FromUserName><![CDATA[sys]]></FromUserName> 
	<CreateTime>1403610513</CreateTime>
	<MsgType><![CDATA[event]]></MsgType>
	<Event><![CDATA[change_contact]]></Event>
	<ChangeType>create_user</ChangeType>
	<UserID><![CDATA[zhangsan]]></UserID>
	<Name><![CDATA[张三]]></Name>
	<Department><![CDATA[1,2,3]]></Department>
	<MainDepartment>1</MainDepartment>
	<IsLeaderInDept><![CDATA[1,0,0]]></IsLeaderInDept>
	<DirectLeader><![CDATA[lisi,wangwu]]></DirectLeader>
	<Position><![CDATA[产品经理]]></Position>
	<Mobile>13800000000</Mobile>
	<Gender>1</Gender>
	<Email><![CDATA[zhangsan@gzdev.com]]></Email>
	<BizMail><![CDATA[zhangsan@qyycs2.wecom.work]]></BizMail>
	<Status>1</Status>
	<Avatar><![CDATA[http://wx.qlogo.cn/mmopen/ajNVd]]>
        </Avatar>
	<Alias><![CDATA[zhangsan]]></Alias>
	<Telephone><![CDATA[020-123456]]></Telephone>
	<Address><![CDATA[广州市]]></Address>
	<ExtAttr>
		<Item>
		<Name><![CDATA[爱好]]></Name>
		<Type>0</Type>
		<Text>
			<Value><![CDATA[旅游]]></Value>
		</Text>
		</Item>
		<Item>
		<Name><![CDATA[卡号]]></Name>
		<Type>1</Type>
		<Web>
			<Title><![CDATA[企业微信]]></Title>
			<Url><![CDATA[https://work.weixin.qq.com]]></Url>
		</Web>
		</Item>
	</ExtAttr>
</xml>

为了看起来更加清晰我将这个xml转JSON 的放在下面

{
  "xml": {
    "ToUserName": "toUser",
    "FromUserName": "sys",
    "CreateTime": "1403610513",
    "MsgType": "event",
    "Event": "change_contact",
    "ChangeType": "create_user",
    "UserID": "zhangsan",
    "Name": "张三",
    "Department": "1,2,3",
    "MainDepartment": "1",
    "IsLeaderInDept": "1,0,0",
    "DirectLeader": "lisi,wangwu",
    "Position": "产品经理",
    "Mobile": "13800000000",
    "Gender": "1",
    "Email": "zhangsan@gzdev.com",
    "BizMail": "zhangsan@qyycs2.wecom.work",
    "Status": "1",
    "Avatar": "http://wx.qlogo.cn/mmopen/ajNVd",
    "Alias": "zhangsan",
    "Telephone": "020-123456",
    "Address": "广州市",
    "ExtAttr": {
      "Item": [
        {
          "Name": "爱好",
          "Type": "0",
          "Text": {
            "Value": "旅游"
          }
        },
        {
          "Name": "卡号",
          "Type": "1",
          "Web": {
            "Title": "企业微信",
            "Url": "https://work.weixin.qq.com"
          }
        }
      ]
    }
  }
}

由此我们发现企微回调的这个xml的层级比较复杂 那接下来我们将正式开始转Javabena对象

引入依赖

        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

根据映射关系建立实体类 并添加JAXB注解

  • @XmlRootElement。这是在JAXB中使用的Object必须有的注解。它定义了XML内容的根元素。
  • @XmlType。它将类映射到XML模式类型。我们可以用它来排列XML中的元素。
  • @XmlTransient。这将确保Object属性不被写入XML中。
  • @XmlAttribute: 这将创建Object属性作为一个属性。
  • @XmlElement(name = “ABC”): 这将创建名称为 "ABC "的元素。
  • @XmlElementWrapper: 注解表示生成一个包装器元素(一般用于集合元素)。
    我们注意到企微回调的xml层级比较复杂 那么这个实体类我们就要思考思考了
    我已经给你们建好了如下

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.*;
import java.util.List;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "xml")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {
        "toUserName",
        "fromUserName",
        "createTime",
        "msgType",
        "event",
        "changeType",
        "userID",
        "name",
        "department",
        "mainDepartment",
        "isLeaderInDept",
        "directLeader",
        "position",
        "mobile",
        "gender",
        "email",
        "bizMail",
        "status",
        "avatar",
        "alias",
        "telephone",
        "address",
        "items",


})
public class MemberXml {
    @XmlElement(name = "ToUserName",required = true)
    private String toUserName;
    @XmlElement(name = "FromUserName",required = true)
    private String fromUserName;
    @XmlElement(name = "CreateTime",required = true)
    private String createTime;
    @XmlElement(name = "MsgType",required = true)
    private String msgType;
    @XmlElement(name = "Event",required = true)
    private String event;
    @XmlElement(name = "ChangeType",required = true)
    private String changeType;
    @XmlElement(name = "UserID",required = true)
    private String userID;
    @XmlElement(name = "Name",required = true)
    private String name;
    @XmlElement(name = "Department",required = true)
    private String department;
    @XmlElement(name = "MainDepartment",required = true)
    private String mainDepartment;
    @XmlElement(name = "IsLeaderInDept",required = true)
    private String isLeaderInDept;
    @XmlElement(name = "DirectLeader",required = true)
    private String directLeader;
    @XmlElement(name = "Position",required = true)
    private String position;
    @XmlElement(name = "Mobile",required = true)
    private String mobile;
    @XmlElement(name = "Gender",required = true)
    private String gender;
    @XmlElement(name = "Email",required = true)
    private String email;
    @XmlElement(name = "BizMail",required = true)
    private String bizMail;
    @XmlElement(name = "Status",required = true)
    private String status;
    @XmlElement(name = "Avatar",required = true)
    private String avatar;
    @XmlElement(name = "Alias",required = true)
    private String alias;
    @XmlElement(name = "Telephone",required = true)
    private String telephone;
    @XmlElement(name = "Address",required = true)
    private String address;
    @XmlElementWrapper(name = "ExtAttr",required = true)
    @XmlElement(name = "Item",required = true)
    private List<Item> items;

}



import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.xml.bind.annotation.*;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "Item")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder ={
        "type",
        "name",
        "webValue",
        "textValue"

} )
public class Item {
    @XmlElement(name = "Type",required = true)
    private String type;

    @XmlElement(name = "Name",required = true)
    private String name;

    @XmlElement(name = "Text",required = true)
    private TextValue textValue;

    @XmlElement(name = "Web",required = true)
    private WebValue webValue;
}


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.*;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Text")
@XmlType(propOrder ={
        "value"
} )
public class TextValue {
    @XmlElement(name = "Value",required = true)
    private String value;
}


import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.xml.bind.annotation.*;

@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
@XmlRootElement(name = "Web")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder ={
        "title",
        "url"
} )
public class WebValue {
    @XmlElement(name = "Title",required = true)
    private String title;
    @XmlElement(name = "Url",required = true)
    private String url;

}

创建xml和实体互转的工具类

public class JaxbUtil {
 
	/**
	 * JavaBean转换成xml
	 * 
	 * @param obj
	 * @param encoding
	 * @return
	 */
	public static String convertToXml(Object obj, String encoding) {
		String result = null;
		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller marshaller = context.createMarshaller();
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
			marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
 
			StringWriter writer = new StringWriter();
			marshaller.marshal(obj, writer);
			result = writer.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
 
		return result;
	}
 
	/**
	 * xml转换成JavaBean
	 * 
	 * @param xml
	 * @param c
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static <T> T converyToJavaBean(String xml, Class<T> c) {
		T t = null;
		try {
			JAXBContext context = JAXBContext.newInstance(c);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			t = (T) unmarshaller.unmarshal(new StringReader(xml));
		} catch (Exception e) {
			e.printStackTrace();
		}
 
		return t;
	}
}

测试

现在我们测试一下 将xml与实体类对象传入

打印测试结果

成功

当然如果有人发现Items没有赋值成功 那就要检查实体类中的注解是否正确

比如根节点是否标记正确