如何通过xml形式发送跟接收报文

该文章只用于客户端如何通过xml格式请求服务端以及将服务端返回的xml格式的报文映射成实体类

服务端请绕道

1.前景

写这篇文章的目的主要是接到一个需求,需要调用长春的核心系统,一直以为是通过json传递数据的,直到测试时才发现核心系统是通过xml来当做报文

2. 开始

2.1 Utils准备

在进行组装xml报文前,我们需要工具类的帮助

这里推荐我们公司内部的XmlUtil,当然网上的也可以

public class XmlUtil {

    /**
     * object => xml
     * @param obj
     * @return
     */
    public static String Object2Xml(Object obj) {
        XStream xs = new XStream();
        xs.processAnnotations(obj.getClass());
        setAnnotations(xs, obj.getClass());
        String xmlStr = xs.toXML(obj);

        String xmlHead = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        return xmlHead + xmlStr;
    }

    /**
     * xml=>object
     * @param xml
     * @param cls
     * @return
     */
    public static <T> T Xml2Object(String xml, Class<T> cls) {
        XStream xs = new XStream();
        xs.processAnnotations(cls);
        setAnnotations(xs, cls);
        T object = (T) xs.fromXML(xml);
        return object;
    }

    /**
     * 注解设置
     * @param xs
     * @param cls
     */
    private static <T> void setAnnotations(XStream xs, Class<T> cls) {
        Field f[] = cls.getDeclaredFields();
        for (int i = 0; i < f.length; i++) {
            Field field = f[i];
            xs.processAnnotations(field.getType());
        }
    }

    public static <T> T toBean(String xml, Class<T> cls) {
        XStream xstream = new XStream(new DomDriver("UTF-8"));
        xstream.processAnnotations(cls);
        xstream.setClassLoader(cls.getClassLoader());
        return (T) xstream.fromXML(xml);
    }

    /**
     * Bean => Xml
     * @param obj
     * @return
     */
    public static String toXml(Object obj,String dtoName) {
        XStream xstream=new XStream(new DomDriver("UTF-8"));
        xstream.autodetectAnnotations(true);
        xstream.alias(dtoName, obj.getClass());
        String xml=xstream.toXML(obj);
        return xml;
    }

    public static String toSoapXml(Object obj,String functionName,String xmlnsirx) {
        String start = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:irx=\""+xmlnsirx+"/\">\n" +
                "   <soapenv:Header/>\n" +
                "   <soapenv:Body>\n"+
                "<irx:"+functionName+">\n";
        String end = "</irx:"+functionName+">\n" +
                "   </soapenv:Body>\n" +
                "</soapenv:Envelope>\n";
        XStream xstream=new XStream(new DomDriver("UTF-8"));
        xstream.autodetectAnnotations(true);
        xstream.alias("requestDTO", obj.getClass());
        String xml=xstream.toXML(obj);
        return start+xml+end;
    }

}

第二个Utils Httputils (网上随便找一个就行,这里推荐我们公司使用的)

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.1.14</version>
</dependency>

导入这个依赖,其中的HttpUtil类就是我们需要的工具类

2.2 请求报文组装

这里请求报文的组装需要用到XmlUtil.toSoapXml(Object obj,String functionName,String xmlnsirx)

这个方法,这里简单解释一下这三个参数的含义。第一个参数当然就是我们的参数,通常是pojo或者map都行,第二个参数可以理解成接口名,后面有示例。第三个参数是XML命名空间。其中第二个跟第三个参数我们都不需要关心,通常是服务端提供的。

示例:

如服务端提供给我们的地址是http://192.168.1.1:9080/icfWeb/ws/TruckTermSearchListWrapper?wsdl

那么,我们的方法这样写:

String fXMLString = XmlUtil.toSoapXml(reqDTO, "TruckTermSearchList","http://irxcx010.afterloan.credit.faf.com");

看到这,这里有个人会问第三个参数http://irxcx010.afterloan.credit.faf.com是哪里来的,这里就需要安装另外一个工具啦。

2.3 SOAPUI介绍

根据上文所提到的,SOAPUI就是我们要提供的工具。这个工具可以理解成发送xml报文的类似postman的工具

2.3.1 下载

SoapUI - Download

2.3.2 使用

打开页面点击新建

 

输入地址(地址找你们服务端提供,不要再问我了)

ProjectName随意取,下面那个WSDL就是你请求的地址

点击ok,看到以下截图,就是我们的第三个参数http://irxcx010.afterloan.credit.faf.com的由来

 

2.3.3 工具小结

这里建议在写java代码前先使用该工具调试一下请求的接口有没有问题,以及接口返回的报文格式是怎么样的,有利于我们后面java代码的编写

2.4 发送请求

直接上代码,简单一行

String res = HttpUtil.post(url, fXMLString);

url就是请求的地址

2.5 返回报文接收

2.5.1 报文截取

 

 我们可以看到返回的报文乱七八糟,而我们真正需要的只是框框里的这几行,我们可以通过StringUtils将返回的报文进行截取。没有该工具类的用String的substring方法也许,是一样的。

这行代码的目的就是截取返回的报文。

res = StringUtils.substringBetween(res, "faf.com/\">", "</ns2:");

截取完,变这样了

<return><applySource>APP</applySource><comtype>3</comtype><ptype>3</ptype><respCode>0000</respCode><respMsg>成功!</respMsg><entityList><id>16190</id><applySource>xd</applySource><applydate>2020-04-26</applydate><bargainNo>JHBHBJC02454</bargainNo><loanmoney>100000.0</loanmoney><nstatus>5</nstatus><payDate>20</payDate><plateNum>895</plateNum><reasonType>15056</reasonType><reasonTypeName>张大哥大哥</reasonTypeName><term>1</term><termType>3</termType><timeLimit>25</timeLimit></entityList></return>

2.5.2 xml与实体类转换

报文返回的形式是String类型,但通常我们都需要将它转化为实体类,下面就介绍如何将xml报文与我们实体类映射

首先,添加依赖

<dependency>
            <groupId>com.thoughtworks.xstream</groupId>
            <artifactId>xstream</artifactId>
            <version>1.4.9</version>
            <scope>compile</scope>
        </dependency>

在实体类里添加注解

@XStreamAlias("return")
public class TruckTermExtendSearchWrapperResDTO {
    @XStreamAlias("comtype")
    private String comtype;

    @XStreamAlias("ptype")
    private String ptype;

    @XStreamAlias("respCode")
    private String respCode;

    @XStreamAlias("respMsg")
    private String respMsg;

    @XStreamAlias("applySource")
    private String applySource;

    @XStreamImplicit(itemFieldName="entityList")
    private List<EntityDTO> entityList;

    public String getComtype() {
        return comtype;
    }

    public void setComtype(String comtype) {
        this.comtype = comtype;
    }

    public String getPtype() {
        return ptype;
    }

    public void setPtype(String ptype) {
        this.ptype = ptype;
    }

    public String getRespCode() {
        return respCode;
    }

    public void setRespCode(String respCode) {
        this.respCode = respCode;
    }

    public String getRespMsg() {
        return respMsg;
    }

    public void setRespMsg(String respMsg) {
        this.respMsg = respMsg;
    }

    public String getApplySource() {
        return applySource;
    }

    public void setApplySource(String applySource) {
        this.applySource = applySource;
    }

    public List<EntityDTO> getEntityList() {
        return entityList;
    }

    public void setEntityList(List<EntityDTO> entityList) {
        this.entityList = entityList;
    }
}

这里需要特别注意的是,如果返回的xml格式有list的话,需要使用@XStreamImplicit(itemFieldName="entityList")注解

注解值只需要跟xml标签映射就行了,简单实用

2.5.3 映射方法

上面讲了实体类添加的注解,注解添加完之后需要通过一个方法进行映射

TruckTermExtendSearchWrapperResDTO resDTO = XmlUtil.toBean(res, TruckTermExtendSearchWrapperResDTO.class);

映射完毕后,看看你的实体类属性是否都映射上了,后面就可以进行自己的业务逻辑了

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以使用Java中的HttpURLConnection类来发送HTTP请求发送XML报文。以下是一个简单的示例代码: ```java import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; public class HttpXmlSender { public static void main(String[] args) throws Exception { // 设置请求的URL URL url = new URL("http://example.com/api"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); // 设置请求方法为POST connection.setRequestMethod("POST"); // 设置请求头的Content-Type为text/xml connection.setRequestProperty("Content-Type", "text/xml"); // 启用输出流,用于发送XML报文 connection.setDoOutput(true); // 构造XML报文 String xmlData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root><data>...</data></root>"; // 发送XML报文 DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream()); outputStream.writeBytes(xmlData); outputStream.flush(); outputStream.close(); // 获取响应结果 int responseCode = connection.getResponseCode(); BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } reader.close(); // 打印响应结果 System.out.println("Response Code: " + responseCode); System.out.println("Response Body: " + response.toString()); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值