该文章只用于客户端如何通过xml格式请求服务端以及将服务端返回的xml格式的报文映射成实体类
服务端请绕道
1.前景写这篇文章的目的主要是接到一个需求,需要调用长春的核心系统,一直以为是通过json传递数据的,直到测试时才发现核心系统是通过xml来当做报文
2. 开始 2.1 Utils准备在进行组装xml报文前,我们需要工具类的帮助
这里推荐我们公司内部的XmlUtil,当然网上的也可以
public class XmlUtil {
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 = "";
return xmlHead + xmlStr;
}
public static T Xml2Object(String xml, Class cls) {
XStream xs = new XStream();
xs.processAnnotations(cls);
setAnnotations(xs, cls);
T object = (T) xs.fromXML(xml);
return object;
}
private static void setAnnotations(XStream xs, Class cls) {
Field f[] = cls.getDeclaredFields();
for (int i = 0; i < f.length; i++) {
Field field = f[i];
xs.processAnnotations(field.getType());
}
}
public static T toBean(String xml, Class cls) {
XStream xstream = new XStream(new DomDriver("UTF-8"));
xstream.processAnnotations(cls);
xstream.setClassLoader(cls.getClassLoader());
return (T) xstream.fromXML(xml);
}
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 = "n" +
" n" +
" n"+
"n";
String end = " n" +
" n" +
" 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 (网上随便找一个就行,这里推荐我们公司使用的)
cn.hutool hutool-all4.1.14
导入这个依赖,其中的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/">", "截取完,变这样了
2.5.2 xml与实体类转换APP 3 3 0000 成功! 16190 xd2020-04-26JHBHBJC02454 100000.0 5 20 895 15056 张大哥大哥 1 3 25 报文返回的形式是String类型,但通常我们都需要将它转化为实体类,下面就介绍如何将xml报文与我们实体类映射
首先,添加依赖
com.thoughtworks.xstream xstream1.4.9 compile 在实体类里添加注解
@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 ListentityList; 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 getEntityList() { return entityList; } public void setEntityList(List entityList) { this.entityList = entityList; } } 这里需要特别注意的是,如果返回的xml格式有list的话,需要使用@XStreamImplicit(itemFieldName="entityList")注解
注解值只需要跟xml标签映射就行了,简单实用
2.5.3 映射方法上面讲了实体类添加的注解,注解添加完之后需要通过一个方法进行映射
TruckTermExtendSearchWrapperResDTO resDTO = XmlUtil.toBean(res, TruckTermExtendSearchWrapperResDTO.class);映射完毕后,看看你的实体类属性是否都映射上了,后面就可以进行自己的业务逻辑了



