最近给安排到上海出差,第一个任务很简单,天天摸鱼,不要太爽,好景不长,第二个需求来了,需要接入第三方接口,当看到https://xxx.xxx.com:8088/invoke.asmx这串url时是懵逼的,这啥玩意。深思五分钟,作为一个面向度娘编程的程序猿,不多想,遇事不决,问度娘。
但找到的方案大多如下:
Service service = new Service();
......
Call call = (Call) service.createCall();
......
String res = String.valueOf(call.invoke(new Object[]{xsXml}));
看样子是能调用,但是我这调用的接口出入参都是XML格式,咋传咋返回,也没做过类似需求大佬可问,第一天,卒。
第二天,满血复活的我又开始了一天的度娘。嗯,通过wsdl2java生成本地webService,看起来可行,试了几次,不好操作,再看,通过eclipse生成webservice客户端代码,就你了。
过程如下:
打开eclipse–>随便新建一个项目–>然后点击File–>New–>other…–>搜索Web Service Client
一顿操作下来生成了五个文件如上图,跟例子里对比东西是少了点,没事,把代码拷到idea,继续莽。
InvokeLocator invokeLocator = new InvokeLocator();
InvokeSoapStub invokeSoapStub = (InvokeSoapStub) invokeLocator.getPort(InvokeSoapStub.class);
SectionOfficeBO sectionOfficeBO = new SectionOfficeBO();
sectionOfficeBO.setTodayClass("1");
RequestBO<SectionOfficeBO> requestBO = new SectionOfficeRequest();
requestBO.setApiName("Entity.GetNodeTree");
requestBO.setClientIP("172.**.**.245");
requestBO.setT(sectionOfficeBO);
XmlBO<SectionOfficeBO> xmlBO = new XmlBO<>();
xmlBO.setHeadBO(getHeadBO(requestBO));
xmlBO.setRequestBO(requestBO);
String xmlStr = invokeSoapStub.processor(XmlUtil.objToXml(xmlBO, false));
入参结构:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Xml>
<Head>
<ChannelCode>xxx</ChannelCode>
<CheckSum>xxx</CheckSum>
<Customer>xxx</Customer>
<DataFormat>xxx</DataFormat>
<From>xxx</From>
<MessageId>xxx</MessageId>
<MessageTime>xxx</MessageTime>
<PoolId>xxx</PoolId>
<SecurityMode>xxx</SecurityMode>
<To>xxx</To>
<Version>xxx</Version>
</Head>
<Request>
<ApiName>xxx</ApiName>
<ClientIP>xxx</ClientIP>
<Parameters>
<xxx>xxx</xxx>
<xxx>xxx</xxx>
</Parameters>
</Request>
</Xml>
Head部分保持不变,Request中ApiName传需要调用的接口名称,Parameters传接口需要的参数。
出参结构:
<?xml version="1.0" encoding="utf-8"?>
<Xml>
<Head>
<Version>xxx</Version>
<SecurityMode>xxx</SecurityMode>
<CheckSum>xxx</CheckSum>
<From>xxx</From>
<To>xxx</To>
<ChannelCode>xxx</ChannelCode>
<Customer>xxx</Customer>
<PoolId>xxx</PoolId>
<DataFormat>xxx</DataFormat>
<MessageId>xxx</MessageId>
<MessageTime>xxx</MessageTime>
<OperatorId />
<SourceId>xxx</SourceId>
</Head>
<Response>
<Status>xxx</Status>
<Code>xxx</Code>
<Message>xxx</Message>
<Data>
<T>
<R>
<xxx>xxx</xxx>
<xxx>xxx</xxx>
</R>
<R>
<xxx>xxx</xxx>
<xxx>xxx</xxx>
</R>
</T>
</Data>
</Response>
</Xml>
Head部分不会变化,主要数据包在R标签里面,能正常返回了,收工。
其涉及的XML解析见下一博客,待续…
补上依赖:
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.5</version>
</dependency>
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.3</version>
</dependency>
补上用RestTemplate调用的方式:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
@Autowired
private RestTemplate restTemplate;
@Value("${xxx}")
private String url;
public XmlBO calling(XmlBO xmlBO) throws Exception {
// 将入参对象转换成xml字符串 组装xml
String xml = getSoapXml(XmlUtil.objToXml(xmlBO, false));
// restTemplate默认使用iso-8859-1 设置为utf-8 防止中文乱码
restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_XML);
MediaType type = MediaType.parseMediaType("text/xml; charset=UTF-8");
headers.setAccept(Collections.singletonList(type));
headers.add("Accept-Encoding", "json");
HttpEntity<String> requestEntity = new HttpEntity<>(xml, headers);
ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
// 转义返回值 当前场景一定会有内容返回 不做非空判断
String resultStr = StringEscapeUtils.unescapeXml(exchange.getBody());
// 如果不包含xml头部信息 则接口调用出错 可转成javabean
if (!resultStr.contains("<?xml version=\"1.0\" encoding=\"utf-8\">")) {
// 用JsonObject将resultStr转换成对象
throw new Exception("对象的getErrorMsg方法");
}
// 返回值不是完整json 剪掉多余部分组装成xml串
int startIndex = resultStr.lastIndexOf("<?xml version=\"1.0\" encoding=\"utf-8\">");
int endIndex = resultStr.indexOf("</ProcessorResult>");
resultStr = resultStr.substring(startIndex, endIndex);
return XmlUtil.xmlToJson(resultStr, XmlBO.class);
}
// webService接口参数得组装soap部分
private String getSoapXml(String xml) {
StringBuffer sb = new StringBuffer();
sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:tem=\"http://tempuri.org/\">\n")
.append(" <soapenv:Header/>\n")
.append(" <soapenv:Body>\n")
.append(" <tem:Processor>\n")
.append(" <!--Optional:-->\n")
.append(" <tem:requestXml><![CDATA[")
.append(xml)
.append("]]></tem:requestXml>\n")
.append(" </tem:Processor>\n")
.append(" </soapenv:Body>\n")
.append("</soapenv:Envelope>");
return sb.toString();
}