SpringBoot之jackson之复杂XML和Object互转、泛型、List、传参/接参

引入依赖

		<!-- lombok插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- jackson xml 转换工具 -->
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
        </dependency>
        <!-- web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

创建第1层请求对象Bsxml

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

import java.io.Serializable;

@Data
@JacksonXmlRootElement(localName = "Bsxml") //XML根节点名称
public class Bsxml<T> implements Serializable {
    
    
    @JacksonXmlProperty(localName = "MsgHeader")
    private MsgHeader msgHeader;//请求头对象
    @JacksonXmlProperty(localName = "MsgBody")
    private T msgBody;//泛型消息体,我这里的泛型是可以去掉的,直接用MsgBody对象,这里只是为了模拟复杂对象。
}

创建第2层请求头对象MsgHeader

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

import java.io.Serializable;

@Data
@ToString
@JacksonXmlRootElement(localName = "MsgHeader")
public class MsgHeader implements Serializable {
    
    
    @JacksonXmlProperty(localName = "Organization")
    private String organization;
    @JacksonXmlProperty(localName = "Sender")
    private String sender;
    @JacksonXmlProperty(localName = "ServiceType")
    private String serviceType;
    @JacksonXmlProperty(localName = "MsgType")
    private String msgType;
    @JacksonXmlProperty(localName = "MsgVersion")
    private String msgVersion;
}

创建第2层请求头体MsgData

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

/**
 * MsgBody对象就是Bsxml里面的泛型T
 */
@Data
@JacksonXmlRootElement(localName = "MsgBody")
public class MsgBody<D> {
    
    
    @JacksonXmlProperty(localName = "Status")
    private Boolean status;//状态
    @JacksonXmlProperty(localName = "Code")
    private Integer code;//成功状态码
    @JacksonXmlProperty(localName = "ErrCode")
    private Integer errCode;//错误状态码
    @JacksonXmlProperty(localName = "Detail")
    private String detail;//详细信息
    @JacksonXmlProperty(localName = "Data")
    private D data;//返回数据,泛型
}

创建第2层请求头体MsgData内层某个Data泛型对象

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

/**
 * LabReportAudit对象就是MsgBody里面的泛型 D
 */
@Data
@JacksonXmlRootElement(localName = "Data")
public class LabReportAudit {
    
    
    @JacksonXmlProperty(localName = "Name")
    private String name;
}

模拟Controller接参传参

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("test")
public class TestController {
    
    

    /**
     * 传xml转json,json转对象
     * @param bsxml Bsxml<T<D>>
     */
    @PostMapping("xmlToObject")
    public void xmlToObject(@RequestBody Bsxml<MsgBody<LabReportAudit>> bsxml) throws JsonProcessingException {
    
    
        log.info("Bsxml转成实体后的信息:{}",bsxml);
        ObjectMapper objectMapper = new ObjectMapper();
        log.info("bsxml JSON:{}", objectMapper.writeValueAsString(bsxml));
    }

    /**
     * 传json转成对象,对象转xml
     * @param bsxml 实体类json
     */
    @PostMapping("objectToXml")
    public void objectToXml(@RequestBody Bsxml<MsgBody<LabReportAudit>> bsxml) throws JsonProcessingException {
    
    
        ObjectMapper objectMapper = new XmlMapper();
        String xmlString = objectMapper.writeValueAsString(bsxml);
        log.info("对象转xml:{}", xmlString);
    }

}

Postman传参

xmlToObject

传参

<Bsxml>
    <MsgHeader>
        <Organization>123456789</Organization>
        <Sender>Meta39</Sender>
        <ServiceType>service</ServiceType>
        <MsgType>msgType</MsgType>
        <MsgVersion>1.0</MsgVersion>
    </MsgHeader>
    <MsgBody>
        <Code>1</Code>
        <Status>true</Status>
        <Detail>描述信息</Detail>
        <Data>
            <Name>名称</Name>
        </Data>
    </MsgBody>
</Bsxml>

在这里插入图片描述

转换

在这里插入图片描述

objectToXml

传参

{
    
    
    "msgHeader": {
    
    
        "organization": "123456789",
        "sender": "Meta39",
        "serviceType": "service",
        "msgType": "msgType",
        "msgVersion": "1.0"
    },
    "msgBody": {
    
    
        "status": true,
        "code": 1,
        "errCode": null,
        "detail": "描述信息",
        "data": {
    
    
            "name": "名称"
        }
    }
}

在这里插入图片描述

转换

在这里插入图片描述

List的转换

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

import java.io.Serializable;
import java.util.List;

@Data
@JacksonXmlRootElement(localName = "Xml")//自定义根路径名称
public class XmlObeject implements Serializable {
    
    
    @JacksonXmlProperty(localName = "Name")
    private String name;
    /**
     * JacksonXmlElementWrapper注解用于指定列表或数组属性在XML中的包装元素,以提供更好的结构化层次和语义意义。
     * 简单理解就是外层用@JacksonXmlElementWrapper,内层用@JacksonXmlProperty。
     */
    @JacksonXmlElementWrapper(localName = "XmlObejectInfos")//序列化
    @JacksonXmlProperty(localName = "XmlInfo")//序列化和反序列化优先级比@JacksonXmlElementWrapper注解高
    private List<XmlObejectInfo> xmlObejectInfos;
}
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Data;

import java.io.Serializable;

@Data
@JacksonXmlRootElement(localName = "XmlInfo")
public class XmlObejectInfo implements Serializable {
    
    
    @JacksonXmlProperty(localName = "Age")
    private Integer age;
}

转换

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class JacksonXmlTests {
    
    

    @Test
    void test() throws JsonProcessingException {
    
    
        XmlMapper xmlMapper = new XmlMapper();

        XmlObeject xmlObeject = new XmlObeject();
        xmlObeject.setName("XML");

        //集合
        List<XmlObejectInfo> xmlObejectInfos = new ArrayList<>();

        XmlObejectInfo xmlObejectInfo = new XmlObejectInfo();
        xmlObejectInfo.setAge(25);

        xmlObejectInfos.add(xmlObejectInfo);

        xmlObeject.setXmlObejectInfos(xmlObejectInfos);

        //序列化成XML字符串
        String xmlString = xmlMapper.writeValueAsString(xmlObeject);
        log.info("{}", xmlString);
        //反序列化成Java对象
        XmlObeject xmlObj = xmlMapper.readValue(xmlString, XmlObeject.class);
        log.info("{}", xmlObj);
    }

}

拓展

有时候我们序列化内容可能无法转换成我们想要的,因为内层的@JacksonXmlRootElement(localName = “XXX”),没有生效,我们可以用反射获取到传过来的类,然后获取JacksonXmlRootElement的注解,序列化成字符串后通过.replace(“”, “<”+otherHeader+“>”).replace(“”, “<”+otherHeader+“/>”)的方式替换掉我们的请求头。

猜你喜欢

转载自blog.csdn.net/weixin_43933728/article/details/131844094