调用webservice服务方式
本人日常工作中经常与不同软件厂商进行接口对接,不同的厂商接口调用方式五花八门,但主要分为两大阵营:http和webservice。本文以Java为例,总结调用webservice服务的几种方式。
一、利用命令或工具将WebService提供的wsdl文件生成对应的java类,这样就可以像调用本地类一样调用webService提供的接口。这种方法的优点是调用简单,无需自己编写太多的东西。缺点同样很明显,生成的代码过于庞大,不便于阅读,显得很累赘。
二、AXIS远程调用,代码如下:
-
import org.apache.axis.Constants;
-
import org.apache.axis.client.Call;
-
import org.apache.axis.client.Service;
-
-
import javax.xml.namespace.QName;
-
-
public class WebServiceTest {
-
-
public static void main(String[] args) {
-
//服务地址
-
String url = "http://127.0.0.1:8080/service-test/services/gateway?wsdl";
-
//命名空间
-
String namespaceURI = "http://www.exampletest.com/";
-
//方法名
-
String method = "invoke";
-
try {
-
Service service = new Service();
-
Call call = (Call) service.createCall();
-
call.setTargetEndpointAddress(url);
-
//设置要调用的方法
-
call.setOperationName(new QName(namespaceURI, method));
-
//设置要返回的数据类型
-
call.setReturnType(new QName(namespaceURI, method), String.class);
-
call.setUseSOAPAction(true);
-
call.setSOAPActionURI(namespaceURI method);
-
//设置入参
-
call.addParameter(new QName(namespaceURI, "consumer"), Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
-
call.addParameter(new QName(namespaceURI, "serviceName"), Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
-
call.addParameter(new QName(namespaceURI, "params"), Constants.XSD_STRING, javax.xml.rpc.ParameterMode.IN);
-
-
//调用方法并传递参数
-
String resultStr = (String) call.invoke(new Object[]{"test", "queryOrder", "{\"tradeno\":\"1648100061001\",\"mchid\":\"10001\"}"});
-
System.out.println("服务调用结果:" resultStr);
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
}
对应jar包的maven依赖:
-
<dependency>
-
<groupId>org.apache.axis</groupId>
-
<artifactId>axis</artifactId>
-
<version>1.4</version>
-
</dependency>
-
<dependency>
-
<groupId>org.apache.axis</groupId>
-
<artifactId>axis-jaxrpc</artifactId>
-
<version>1.4</version>
-
</dependency>
该种方式调用简单,一般不需要自己组织请求报文和解析返回报文 。
三、通过HttpURLConnection进行调用,代码如下:
-
import java.io.BufferedReader;
-
import java.io.InputStream;
-
import java.io.InputStreamReader;
-
import java.io.OutputStream;
-
import java.net.HttpURLConnection;
-
import java.net.URL;
-
-
public class WebServiceTest {
-
-
public static void main(String[] args) throws Exception {
-
//服务地址
-
String url = "http://127.0.0.1:8080/service-test/services/gateway?wsdl";
-
//第一步:创建服务地址
-
URL httpUrl = new URL(url);
-
//第二步:打开一个通向服务地址的连接
-
HttpURLConnection connection = (HttpURLConnection) httpUrl.openConnection();
-
//第三步:设置参数
-
//3.1发送方式设置:POST必须大写
-
connection.setRequestMethod("POST");
-
//3.2设置数据格式:content-type,这个根据实际情况来确定
-
connection.setRequestProperty("content-type", "application/atom xml;charset=utf-8");
-
//3.3设置输入输出,因为默认新创建的connection没有读写权限,
-
connection.setDoInput(true);
-
connection.setDoOutput(true);
-
-
//第四步:组织SOAP数据,发送请求
-
String soapXML = getXML("test", "queryOrder", "{\"tradeno\":\"1648100061003\",\"mchid\":\"10001\"}");
-
//将信息以流的方式发送出去
-
OutputStream os = connection.getOutputStream();
-
os.write(soapXML.getBytes());
-
//第五步:接收服务端响应,打印
-
InputStream is = connection.getInputStream();
-
InputStreamReader isr = new InputStreamReader(is);
-
BufferedReader br = new BufferedReader(isr);
-
-
StringBuilder sb = new StringBuilder();
-
String temp = null;
-
while(null != (temp = br.readLine())){
-
sb.append(temp);
-
}
-
System.out.println("服务调用结果:" sb.toString());
-
is.close();
-
isr.close();
-
br.close();
-
}
-
-
/**
-
* @Author admin
-
* @Description 组装xml报文
-
* @Date 15:47 2022/5/1
-
* @Param [consumer, serviceName, para]
-
* @return java.lang.String
-
**/
-
public static String getXML(String consumer, String serviceName, String paraStr){
-
String soapXML = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:dar=\"http://www.darewayhealth.com/\">\n"
-
" <soapenv:Header/>\n"
-
" <soapenv:Body>\n"
-
" <dar:invoke>\n"
-
" <!--Optional:-->\n"
-
" <dar:consumerId>" consumer "</dar:consumerId>\n"
-
" <!--Optional:-->\n"
-
" <dar:serviceName>" serviceName "</dar:serviceName>\n"
-
" <!--Optional:-->\n"
-
" <dar:params>" paraStr "</dar:params>\n"
-
" </dar:invoke>\n"
-
" </soapenv:Body>\n"
-
"</soapenv:Envelope>";
-
return soapXML;
-
}
-
}
该种方式一般需要自己组织请求的xml报文,自己解析返回的xml报文。
四、通过HttpClient进行调用,代码如下:
-
import org.apache.commons.httpclient.HttpClient;
-
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
-
import org.apache.commons.httpclient.methods.PostMethod;
-
import org.apache.commons.httpclient.methods.RequestEntity;
-
-
import java.io.ByteArrayInputStream;
-
import java.io.InputStream;
-
-
public class WebServiceTest {
-
-
public static void main(String[] args) throws Exception {
-
//服务地址
-
String url = "http://127.0.0.1:8080/service-test/services/gateway?wsdl";
-
HttpClient httpClient = new HttpClient();
-
PostMethod postMethod = new PostMethod(url);
-
-
String soap = getXML("test", "queryOrder", "{\"tradeno\":\"1648100061003\",\"mchid\":\"10001\"}");
-
-
try {
-
byte[] b = soap.getBytes("utf-8");
-
InputStream is = new ByteArrayInputStream(b, 0, b.length);
-
RequestEntity re = new InputStreamRequestEntity(is, b.length,
-
"application/atom;charset=utf-8");
-
postMethod.setRequestEntity(re);
-
httpClient.executeMethod(postMethod);
-
String soapResponseData = postMethod.getResponseBodyAsString();
-
System.out.println("服务调用结果:" soapResponseData);
-
postMethod.releaseConnection();
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
-
/**
-
* @Author admin
-
* @Description 组装xml报文
-
* @Date 15:47 2022/5/1
-
* @Param [consumer, serviceName, para]
-
* @return java.lang.String
-
**/
-
public static String getXML(String consumer, String serviceName, String paraStr){
-
String soapXML = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:dar=\"http://www.darewayhealth.com/\">\n"
-
" <soapenv:Header/>\n"
-
" <soapenv:Body>\n"
-
" <dar:invoke>\n"
-
" <!--Optional:-->\n"
-
" <dar:consumerId>" consumer "</dar:consumerId>\n"
-
" <!--Optional:-->\n"
-
" <dar:serviceName>" serviceName "</dar:serviceName>\n"
-
" <!--Optional:-->\n"
-
" <dar:params>" paraStr "</dar:params>\n"
-
" </dar:invoke>\n"
-
" </soapenv:Body>\n"
-
"</soapenv:Envelope>";
-
return soapXML;
-
}
-
}
该方式的特点同方式三。
五、通过CloseableHttpClient进行调用,代码如下:
-
import org.apache.http.Consts;
-
import org.apache.http.HttpEntity;
-
import org.apache.http.client.config.RequestConfig;
-
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.HttpClients;
-
import org.apache.http.util.EntityUtils;
-
-
import java.io.IOException;
-
-
public class WebServiceTest {
-
-
public static void main(String[] args) throws Exception {
-
//服务地址
-
String url = "http://127.0.0.1:8080/service-test/services/gateway?wsdl";
-
int timeout = 180000;
-
CloseableHttpClient httpClient = HttpClients.createDefault();
-
RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(timeout).setConnectionRequestTimeout(timeout).setSocketTimeout(timeout).build();
-
HttpPost httpPost = null;
-
CloseableHttpResponse response = null;
-
HttpEntity resEntity = null;
-
-
try {
-
httpPost = new HttpPost(url);
-
httpPost.setConfig(defaultRequestConfig);
-
String xmlStr = getXML("test", "queryOrder", "{\"tradeno\":\"1648100061003\",\"mchid\":\"10001\"}");
-
httpPost.setEntity(new StringEntity(xmlStr, Consts.UTF_8));
-
response = httpClient.execute(httpPost);
-
resEntity = response.getEntity();
-
String resStr = EntityUtils.toString(resEntity, Consts.UTF_8);
-
EntityUtils.consume(resEntity);
-
System.out.println("服务调用结果:" resStr);
-
} catch (Exception e) {
-
e.printStackTrace();
-
} finally {
-
try {
-
if (response != null) {
-
response.close();
-
}
-
} catch (IOException var21) {
-
var21.printStackTrace();
-
}
-
}
-
}
-
-
/**
-
* @Author admin
-
* @Description 组装xml报文
-
* @Date 15:47 2022/5/1
-
* @Param [consumer, serviceName, para]
-
* @return java.lang.String
-
**/
-
public static String getXML(String consumer, String serviceName, String paraStr){
-
String soapXML = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:dar=\"http://www.darewayhealth.com/\">\n"
-
" <soapenv:Header/>\n"
-
" <soapenv:Body>\n"
-
" <dar:invoke>\n"
-
" <!--Optional:-->\n"
-
" <dar:consumerId>" consumer "</dar:consumerId>\n"
-
" <!--Optional:-->\n"
-
" <dar:serviceName>" serviceName "</dar:serviceName>\n"
-
" <!--Optional:-->\n"
-
" <dar:params>" paraStr "</dar:params>\n"
-
" </dar:invoke>\n"
-
" </soapenv:Body>\n"
-
"</soapenv:Envelope>";
-
return soapXML;
-
}
-
}
该方式的特点同方式三。
六、使用XFire调用,代码如下:
-
import org.codehaus.xfire.client.Client;
-
import java.net.URL;
-
-
public class WebServiceTest {
-
-
public static void main(String[] args) {
-
try {
-
//服务地址
-
String url = "http://127.0.0.1:8080/service-test/services/gateway?wsdl";
-
//方法名
-
String method = "invoke";
-
Client client = new Client(new URL(url));
-
Object[] result = client.invoke(method, new Object[]{"test", "queryOrder", "{\"tradeno\":\"1648100061003\",\"mchid\":\"10001\"}"});
-
System.out.println("服务调用结果:" result[0]);
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
}
需要xfire-all-1.2.6.jar包,maven依赖如下:
-
<dependency>
-
<groupId>org.codehaus.xfire</groupId>
-
<artifactId>xfire-all</artifactId>
-
<version>1.2.6</version>
-
</dependency>
该方式比较古老了,本文只做介绍,后面都用新版本CXF了。值得一提的是,在测试该方式的时候报了一个错误,如下:
-
Exception in thread "main" java.lang.NoSuchMethodError: org.apache.ws.commons.schema.XmlSchemaComplexType.getAttributes()Lorg/apache/ws/commons/schema/XmlSchemaObjectCollection;
-
at org.codehaus.xfire.wsdl11.parser.WSDLServiceBuilder.hasAttributes(WSDLServiceBuilder.java:662)
-
at org.codehaus.xfire.wsdl11.parser.WSDLServiceBuilder.isWrapped(WSDLServiceBuilder.java:582)
-
at org.codehaus.xfire.wsdl11.parser.WSDLServiceBuilder.visit(WSDLServiceBuilder.java:392)
-
at org.codehaus.xfire.wsdl11.parser.WSDLServiceBuilder.build(WSDLServiceBuilder.java:195)
-
at org.codehaus.xfire.client.Client.initFromDefinition(Client.java:264)
-
at org.codehaus.xfire.client.Client.<init>(Client.java:236)
-
at org.codehaus.xfire.client.Client.<init>(Client.java:246)
方法不存在,原因其实是包冲突,xfire所依赖的低版本的XmlSchema-1.1.jar与cxf所依赖的高版本的xmlschema-core-2.2.5.jar冲突,删掉高版本的就解决了。
七、通过CXF调用,代码如下:
-
import org.apache.cxf.endpoint.Client;
-
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
-
-
public class WebServiceTest {
-
-
public static void main(String[] args) {
-
//服务地址
-
String url = "http://127.0.0.1:8080/service-test/services/gateway?wsdl";
-
//方法名
-
String method = "invoke";
-
try {
-
DynamicClientFactory factory = DynamicClientFactory.newInstance();
-
Client client = factory.createClient(url);
-
Object[] resultObject = client.invoke(method, new Object[]{"test", "queryOrder", "{\"tradeno\":\"1648100061003\",\"mchid\":\"10001\"}"});
-
String resultStr = resultObject[0].toString(); //接口调用结果
-
System.out.println("服务调用结果:" resultStr);
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
}
该种方式一般不需要自己组织请求报文和解析返回报文,比较简单。
总结,以上七种方式各有特点,推荐使用AXIS方式或CXF方式或者HTTP方式中的其中一种。
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhhkighk
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
微信运动停用后别人还能看到步数吗
PHP中文网 07-22