IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 调用webservice服务方式总结 -> 正文阅读

[Java知识库]调用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方式中的其中一种。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-06-08 18:52:54  更:2022-06-08 18:56:58 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:12:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码