在权衡了麻烦程度以及适用性之后,本人使用http直接发送xml报文直接调用WebService。
准备工作:先提供一个WebService
第一步:创建一个java项目(这里不是重点,创建普通java项目就行),并创建几个java文件
说明:
User被创建用于辅助演示的;
MyWebService是用来编写提供的WebService服务的;
MyServer中是用来发布MyWebService的。
User:
MyWebService:
MyServer:
第二步:检查一下发布是否成功,运行MyServer主函数,并访问http://127.0.0.1:9527/webservice/test?wsdl
说明:发布WebService成功
第三步:下载SoapUI工具,并根据http://127.0.0.1:9527/webservice/test?wsdl获得xml模板
使用样例:
可见:SoapUI只需一分钟即可初步简单使用,上手并不难。
使用Http调用WebService
第一步:创建一个项目,并在pom.xml中引入依赖
pom.xml除了基本的依赖外,还需要
<!-- 如果使用的是 springframework的RestTemplate发送http,那么需要引入此依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--
使用apache的httpclient发送http,需要引入httpclient依赖;
使用OMElement需要引入axis2-transport-http依赖;改以来本身带有httpclient依赖,所以
我们不在需要单独引入httpclient依赖了
-->
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2-transport-http</artifactId>
<version>1.7.8</version>
</dependency>
第二步:使用HTTP调用WebService
给出调用WebService核心逻辑图片版:
给出完整(含HTTP工具类)的文字版:
package com;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.List;
import javax.xml.stream.XMLStreamException;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpHeaders;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestTemplate;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AbcAxis2DemoApplicationTests {
@Test
public void test() throws XMLStreamException, ClientProtocolException, IOException {
// webservice的wsdl地址
final String wsdlURL = "http://127.0.0.1:9527/webservice/test?wsdl";
// 设置编码。(因为是直接传的xml,所以我们设置为text/xml;charset=utf8)
final String contentType = "text/xml;charset=utf8";
/// 拼接要传递的xml数据(注意:此xml数据的模板我们根据wsdlURL从SoapUI中获得,只需要修改对应的变量值即可)
String name = "邓沙利文";
Integer age = 24;
String motto = "一杆清台!";
StringBuffer xMLcontent = new StringBuffer("");
xMLcontent.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap"
+ "/envelope/\" xmlns:ser=\"http://server.aspire.com/\">\n");
xMLcontent.append(" <soapenv:Header/>\n");
xMLcontent.append(" <soapenv:Body>\n");
xMLcontent.append(" <ser:userMethod>\n");
xMLcontent.append(" <!--Optional:-->\n");
xMLcontent.append(" <name>" + name + "</name>\n");
xMLcontent.append(" <!--Optional:-->\n");
xMLcontent.append(" <age>" + age + "</age>\n");
xMLcontent.append(" <!--Optional:-->\n");
xMLcontent.append(" <motto>" + motto + "</motto>\n");
xMLcontent.append(" </ser:userMethod>\n");
xMLcontent.append(" </soapenv:Body>\n");
xMLcontent.append("</soapenv:Envelope>");
// 调用工具类方法发送http请求
String responseXML = HttpSendUtil.doHttpPostByHttpClient(wsdlURL,contentType, xMLcontent.toString());
// 当然我们也可以调用这个工具类方法发送http请求
// String responseXML = HttpSendUtil.doHttpPostByRestTemplate(wsdlURL, contentType, xMLcontent.toString());
// 利用axis2的OMElement,将xml数据转换为OMElement
OMElement omElement = OMXMLBuilderFactory
.createOMBuilder(new ByteArrayInputStream(responseXML.getBytes()), "utf-8").getDocumentElement();
// 根据responseXML的数据样式,定位到对应element,然后获得其childElements,遍历
Iterator<OMElement> it = omElement.getFirstElement().getFirstElement().getFirstElement().getChildElements();
while (it.hasNext()) {
OMElement element = it.next();
System.out.println("属性名:" + element.getLocalName() + "\t属性值:" + element.getText());
}
}
}
/**
* HTTP工具类
*
* @author JustryDeng
* @DATE 2018年9月22日 下午10:29:08
*/
class HttpSendUtil {
/**
* 使用apache的HttpClient发送http
*
* @param wsdlURL
* 请求URL
* @param contentType
* 如:application/json;charset=utf8
* @param content
* 数据内容
* @DATE 2018年9月22日 下午10:29:17
*/
static String doHttpPostByHttpClient(final String wsdlURL, final String contentType, final String content)
throws ClientProtocolException, IOException {
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 创建Post请求
HttpPost httpPost = new HttpPost(wsdlURL);
StringEntity entity = new StringEntity(content.toString(), "UTF-8");
// 将数据放入entity中
httpPost.setEntity(entity);
httpPost.setHeader("Content-Type", contentType);
// 响应模型
CloseableHttpResponse response = null;
String result = null;
try {
// 由客户端执行(发送)Post请求
response = httpClient.execute(httpPost);
// 从响应模型中获取响应实体
// 注意:和doHttpPostByRestTemplate方法用的不是同一个HttpEntity
org.apache.http.HttpEntity responseEntity = response.getEntity();
System.out.println("响应ContentType为:" + responseEntity.getContentType());
System.out.println("响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
result = EntityUtils.toString(responseEntity);
System.out.println("响应内容为:" + result);
}
} finally {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
}
return result;
}
/**
* 使用springframework的RestTemplate发送http
*
* @param wsdlURL
* 请求URL
* @param contentType
* 如:application/json;charset=utf8
* @param content
* 数据内容
* @DATE 2018年9月22日 下午10:30:48
*/
static String doHttpPostByRestTemplate(final String wsdlURL, final String contentType, final String content) {
// http使用无参构造;https需要使用有参构造
RestTemplate restTemplate = new RestTemplate();
// 解决中文乱码
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
converterList.remove(1);
HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
converterList.add(1, converter);
restTemplate.setMessageConverters(converterList);
// 设置Content-Type
HttpHeaders headers = new HttpHeaders();
headers.remove("Content-Type");
headers.add("Content-Type", contentType);
// 数据信息封装
// 注意:和doHttpPostByHttpClient方法用的不是同一个HttpEntity
org.springframework.http.HttpEntity<String> formEntity = new org.springframework.http.HttpEntity<String>(
content, headers);
String result = restTemplate.postForObject(wsdlURL, formEntity, String.class);
return result;
}
}
测试一下
运行测试类,控制台输出内容为(为了看起来明明晰,本人将输出内容粘贴出来整理了一下):
提示:代码中omElement.getFirstElement()获得的即为body节点。
说明:本人之所以使用HTTP调用WebService时,还引入了axis2的OMElement,主要是看中了
XML、OMElement、Java对象之间的相互转换功能,由于本人最近较忙,所以此三者的转换,留待后面有时间再
学习分享。