XML转对象,对象转XML,Soap转换

最近项目需要接入动环监控设备,使用WebService走B接口调用。调用格式Soap,参数为XML格式,为此记录一下XML转JavaBean,JavaBean转XML,以及从Soap报文中提取XML,生成Soap的方法等。

1.引入主要依赖
~~

    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>

~~
2.Soap工具类

具体Soap的参数格式需要看具体参数

import cn.hutool.http.ContentType;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import com.imr.common.util.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;

import javax.xml.soap.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;

@Slf4j
public class SoapUtil {


    /**
     * 构建请求体-前部分
     *
     * @return
     * @throws
     */
    public static String generateSoap(String xml) {
        try {
            // 创建空的SOAP消息
            MessageFactory messageFactory = MessageFactory.newInstance();
            SOAPMessage soapMessage = messageFactory.createMessage();

            // 获取SOAP消息的SOAP部分
            SOAPPart soapPart = soapMessage.getSOAPPart();

            // 创建SOAP消息的SOAP Envelope
            SOAPEnvelope envelope = soapPart.getEnvelope();
            //删除默认的前缀
            envelope.removeNamespaceDeclaration("SOAP-ENV");
            // 设置SOAP Envelope的命名空间
            envelope.addNamespaceDeclaration("soap", "http://schemas.xmlsoap.org/soap/envelope/");
            envelope.addNamespaceDeclaration("xsi", "http://www.w3.org/2001/XMLSchema-instance");
            envelope.addNamespaceDeclaration("xsd", "http://www.w3.org/2001/XMLSchema");
            envelope.setPrefix("soap");
            //去掉头节点
            SOAPHeader header = envelope.getHeader();
            header.detachNode();
            // 创建SOAP消息的SOAP Body
            SOAPBody body = envelope.getBody();
            body.setPrefix("soap");
            SOAPElement invoke = body.addChildElement("invoke", "", "http://SUService.chinatelecom.com");
            SOAPElement xmlData = invoke.addChildElement("xmlData", "", "");
            xmlData.addTextNode(xml);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            soapMessage.writeTo(outputStream);
            return StringEscapeUtils.unescapeXml(outputStream.toString());
        } catch (Exception e) {
            log.error("构造SOAP参数失败:{}", xml, e);
        }
        return "";
    }

    /**
     * 生成soap并且发送请求-返回响应的soap报文
     *
     * @param
     */
    public static <T> String sendRequest(T obj, String url) {
        String xml = XmlUtil.javaBeanToXml(obj);
        String soap = generateSoap(xml);
        HttpRequest post = HttpUtil.createPost(url);
        post.contentType(ContentType.XML.getValue());
        log.info(soap);
        return post.body(soap).execute().body();
    }

    /**
     * 从返回的soap中提取(body)-xml
     *
     * @param
     * @return
     */
    public static String getResponseXml(String soapXml) {
        try {
            // 创建SOAP消息工厂
            MessageFactory factory = MessageFactory.newInstance();
            // 创建SOAP消息
            SOAPMessage message;
            ByteArrayInputStream inputStream = new ByteArrayInputStream(soapXml.getBytes());
            message = factory.createMessage(null, inputStream);
            // 提取SOAP消息的Body部分
            SOAPBody body = message.getSOAPBody();
            return body.getTextContent();
        } catch (Exception e) {
            log.error("获取SOAP参数失败:{}", soapXml, e);
        }
        return "";
    }


}

3.XML解析工具类

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;

import java.text.SimpleDateFormat;
import java.util.TimeZone;

@Slf4j
public class XmlUtil {

    private XmlUtil() {
    }
    private static final XmlMapper XM = new XmlMapper();

    static {
        // 对象的所有字段全部列入,还是其他的选项,可以忽略null等
        XM.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // 设置Date类型的序列化及反序列化格式
        XM.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 忽略空Bean转json的错误
        XM.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 忽略未知属性,防止json字符串中存在,java对象中不存在对应属性的情况出现错误
        XM.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注册一个时间序列化及反序列化的处理模块,用于解决jdk8中localDateTime等的序列化问题
        XM.registerModule(new JavaTimeModule());
        //设置时区
        XM.setTimeZone(TimeZone.getTimeZone("GMT+8"));

    }
    public static <T> T xmlToJavaBean(String xmlStr, Class<T> clz) {
        try {
            return XM.readValue(xmlStr, clz);
        } catch (Exception e) {
            log.error("XML序列化失败", e);
            return null;
        }

    }

    public static <T> T xmlToJavaBean(String xmlStr, TypeReference<T> valueTypeRef) {
        try {
            return XM.readValue(xmlStr, valueTypeRef);
        } catch (Exception e) {
            log.error("XML序列化失败", e);
            return null;
        }
    }

    public static String javaBeanToXml(Object o) {
        try {
            return XM.writeValueAsString(o);
        } catch (Exception e) {
            log.error("XML序列化失败", e);
            return null;
        }
    }


}


4. 创建类用来接收XML解析后的参数

XML格式
在这里插入图片描述

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;


@JacksonXmlRootElement(localName = "root")
public class RequesttParam {
    @JacksonXmlProperty(localName = "EXECUTE_ORDER")
    private String excuTeOrder;
    @JacksonXmlProperty(localName = "TT_ID")
    private String ttId;
    @JacksonXmlProperty(localName = "SrcFlag")
    private String srcFlag;
    @JacksonXmlProperty(localName = "FinishTime")
    private String finishTime;
    @JacksonXmlProperty(localName = "Longitude")
    private String longitude;
    @JacksonXmlProperty(localName = "Latitude")
    private String latitude;
    @JacksonXmlProperty(localName = "OperatorName")
    private String operatorName;

}

有的XML格式比较复杂,节点比较多,或者节点上仍然有元素,比如下面这这些
在这里插入图片描述
在这里插入图片描述
对于节点上有元素点的,比如Device上有元素ID,这种情况只需要在之前注解上加个属性即可

     @JacksonXmlProperty(localName = "ID",isAttribute = true)
        private String deviceId;

而对于节点下有多个节点的情况,JackSon一样提供了解决办法,如下

 @JacksonXmlElementWrapper(useWrapping=false)
        @JacksonXmlProperty(localName = "SPID")
        private List<String> spid;

如有误,请理解!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值