WebService客户端几种实现方式

2023-10-31

一、发布一个webservice服务(jdk原生)

1.编写服务接口

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 * 
 * 基于soap协议(http+xml)的服务
 */
@WebService(name = "Login",// 定义Port名称
serviceName = "MyService", // 修改WebService服务名称
targetNamespace = "http://com.soft.ws/my" // 定义命名空间,默认为倒置的包名
)
public interface MyService {
	// 提供一个对外公开的服务
	@WebMethod(operationName = "authorization")
	// 修改方法名
	String authorization(@WebParam(name = "userId") String userId,
			@WebParam(name = "password") String password);
}

2.服务实现类

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 * 服务实现类
 */
@WebService(endpointInterface = "com.soft.platform.webservice.server.MyService",
name = "Login",// 定义Port名称
serviceName = "MyService", // 修改WebService服务名称
targetNamespace = "http://com.soft.ws/my" // 定义命名空间,默认为倒置的包名
//服务实现类和接口的注解要一样全
)
public class MyServiceImpl implements MyService {

	@WebMethod(operationName = "authorization" // 修改方法名
	)
	@Override
	public String authorization(
			@WebParam(name = "userId") String userId,
			@WebParam(name = "password") String password) {
		if ("admin".equals(userId) && "123456".equals(password)) {
			return "success";
		}
		return "error";
	}

}

3.发布服务

运行下面的代码 发布WebService服务

/**
 * 发布服务
 *
 */
public class MyPublisher {
	
	public static void main(String[] args) {
		//指定服务url
		String url = "http://192.168.0.101:8089/myservice";
		//指定服务实现类
		MyService server = new MyServiceImpl();
		//采用命令行发布者Endpoint发布服务
		Endpoint.publish(url, server);
	}

}

4.浏览器查看是否发布成功

打开浏览器地址栏输入:http://192.168.0.101:8089/myservice?wsdl
结果如下:
在这里插入图片描述

二、几种客户端调用方式

上面发布的服务不要关闭,编写另外一个客户端类来调用上面发布服务,有以下几种方法来调用服务

1、jdk原生调用(需要获取服务接口文件)

import java.net.URL;

import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import com.soft.platform.webservice.server.MyService;

public class WsClient {

	public static void main(String[] args) throws Exception {
		URL url = new URL("http://192.168.0.101:8089/myservice?wsdl");
		// 指定命名空间和服务名称
		QName qName = new QName("http://com.soft.ws/my", "MyService");
		Service service = Service.create(url, qName);
		// 通过getPort方法返回指定接口
		MyService myServer = service.getPort(new QName("http://com.soft.ws/my",
				"LoginPort"), MyService.class);
		// 调用方法 获取返回值
		String result = myServer.authorization("admin", "123456");
		System.out.println(result);
	}

}
返回结果: success

2、用import命令生成客户端代码

wsimport -d d:/webservice -keep -p com.soft.test.wsimportClient -verbose http://192.168.0.101:8089/myservice?wsdl
这里写图片描述

public static void main(String[] args) {
		MyService_Service service = new MyService_Service();
		MyService login = service.getLoginPort();
		String result = login.authorization("admin", "123456");
		System.out.println(result);
	}

wsimport是jdk自带的,可以根据wsdl文档生成客户端调用代码的工具。
无论服务器端的WebService是用什么语言写的,都将在客户端生成Java代码。

wsimport.exe位于JAVA_HOME\bin目录下.

3、cxf类库 两种调用方式。

Apache CXF 是开源的WebService框架,CXF帮助您使用前端编程api(如JAX-WS和JAX-RS)构建和开发服务。这些服务可以使用多种协议,如SOAP、XML/HTTP、RESTful HTTP或CORBA,并在多种传输协议(如HTTP、JMS或JBI)上工作。
官网地址:http://cxf.apache.org/

public static void main(String[] args) {
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.setServiceClass(MyService.class);
		factory.setAddress("http://192.168.0.101:8089/myservice?wsdl");
		// 需要服务接口文件
		MyService client = (MyService) factory.create();
		String result = client.authorization("admin", "123456");
		System.out.println(result);
	}
public static void main(String[] args) throws Exception {
		//采用动态工厂方式 不需要指定服务接口
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		Client client = dcf
				.createClient("http://192.168.0.101:8089/myservice?wsdl");
		QName qName = new QName("http://com.soft.ws/my", "authorization");
		Object[] result = client.invoke(qName,
				new Object[] { "admin", "123456" });
		System.out.println(result[0]);
	}

注意事项:
apache-cxf-3.2.XX 开始JDK最低要求要JDK1.8
apache-cxf-3.1.XX还是支持JDK1.7
cxf的WebServices客户端代码maven依赖如下:

<dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.xx.xx</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.xx.xx</version>
        </dependency>
    </dependencies>

如果是独立的jar部署的,cxf客户端需要的jar包如下:
在这里插入图片描述

4、axis调用方式

这个例子是比较老的axis版本作为客户端了,最新版官网

import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;

import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ServiceException;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;

public class WsAClient {
     /**
	 * 跨平台调用Web Service出现
	 *  faultString: 服务器未能识别 HTTP 头 SOAPAction 的值: 
	 * JAX-WS规范不需要SoapAction,但是.NET需要,所以产生了这个错误。 
	 * options.setAction("目标的TargetNameSpace"+"调用的方法名");
	 */
	public static void main(String[] args) {
		String url = "http://192.168.0.101:8089/myservice?wsdl";
		Service service = new Service();
		try {
			Call call = (Call) service.createCall();
			call.setTargetEndpointAddress(new URL(url));
			// WSDL里面描述的接口名称(要调用的方法)
			call.setOperationName(new QName("http://com.soft.ws/my",
					"authorization"));
			//跨平台调用加上这个
		   call.setUseSOAPAction(true);
		   call.setSOAPActionURI("http://com.soft.ws/my/authorization");
			// 接口方法的参数名, 参数类型,参数模式 IN(输入), OUT(输出) or INOUT(输入输出)
			call.addParameter("userId", XMLType.XSD_STRING, ParameterMode.IN);
			call.addParameter("password", XMLType.XSD_STRING, ParameterMode.IN);
			// 设置被调用方法的返回值类型
			call.setReturnType(XMLType.XSD_STRING);
			// 设置方法中参数的值
			Object result = call.invoke(new Object[] { "admin", "123456" });

			System.out.println(result.toString());
		} catch (ServiceException | RemoteException | MalformedURLException e) {
			e.printStackTrace();
		}
	}

}

axis方式依赖的相关jar包如下:
在这里插入图片描述

5、httpClient调用方式。

(1)maven依赖如下

  <properties>
   <httpclient.version>4.5.6</httpclient.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>${httpclient.version}</version>
    </dependency>
  </dependencies>

(2)httpclient作为客户端调用webservice。代码如下

/*
 * Copyright (c)
 */
package test;

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.nio.charset.Charset;

/**
 * webservice客户端
 *
 * @author David Lin
 * @version: 1.0
 * @date 2018-09-09 12:16
 */
public class SoapClient {

    public static void main(String args[]) throws Exception {
        //soap服务地址
        String url = "http://localhost:8888/ssm/Services/UserService?wsdl";
        StringBuilder soapBuilder = new StringBuilder(64);
        soapBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        soapBuilder.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.soft.com/\">");
        soapBuilder.append("   <soapenv:Header/>");
        soapBuilder.append("       <soapenv:Body>");
        soapBuilder.append("             <web:authorization>");
        soapBuilder.append("                     <userId>").append("admin").append("</userId>");
        soapBuilder.append("                     <password>").append("123456").append("</password>");
        soapBuilder.append("               </web:authorization>");
        soapBuilder.append("    </soapenv:Body>");
        soapBuilder.append("</soapenv:Envelope>");

        //创建httpcleint对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        //创建http Post请求
        HttpPost httpPost = new HttpPost(url);
        // 构建请求配置信息
        RequestConfig config = RequestConfig.custom().setConnectTimeout(1000) // 创建连接的最长时间
                .setConnectionRequestTimeout(500) // 从连接池中获取到连接的最长时间
                .setSocketTimeout(3 * 1000) // 数据传输的最长时间10s
                .build();
        httpPost.setConfig(config);
        CloseableHttpResponse response = null;
        try {
            //采用SOAP1.1调用服务端,这种方式能调用服务端为soap1.1和soap1.2的服务
            httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");

            //采用SOAP1.2调用服务端,这种方式只能调用服务端为soap1.2的服务
            // httpPost.setHeader("Content-Type", "application/soap+xml;charset=UTF-8");
            StringEntity stringEntity = new StringEntity(soapBuilder.toString(), Charset.forName("UTF-8"));
            httpPost.setEntity(stringEntity);
            response = httpClient.execute(httpPost);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                String content = EntityUtils.toString(response.getEntity(), "UTF-8");
                System.out.println(content);

            } else {
                System.out.println("调用失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                response.close();
            }
            if (null != httpClient) {
                httpClient.close();
            }
        }


    }
}

返回结果为:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
	<soap:Body>
		<ns2:authorizationResponse xmlns:ns2="http://webservice.soft.com/">
			<return>success</return>
		</ns2:authorizationResponse>
	</soap:Body>
</soap:Envelope>

(3)用Jsoup提取响应数据。
maven依赖

<properties>
      <jsoup.version>1.11.3</jsoup.version>
  </properties>
  
  <dependencies>
  
    <dependency>
      <groupId>org.jsoup</groupId>
      <artifactId>jsoup</artifactId>
      <version>${jsoup.version}</version>
    </dependency>
    
  </dependencies>

代码如下:

 Document soapRes = Jsoup.parse(content);
 Elements returnEle = soapRes.getElementsByTag("return");

 System.out.println("调用结果为:"+returnEle.text());

6、SoapUI

soapUI是一个开源测试工具,通过soap/http来检查、调用、实现Web Service的功能/负载/符合性测试。
用这个图形化工具也可以调用WebService服务,作为测试使用。
在这里插入图片描述

7、其他

只要WSDL服务地址能够访问,就能根据wsdl描述的信息手动造一个 服务接口文件 ,这样客户端就可以使用这个接口文件调用服务。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebService客户端几种实现方式 的相关文章

  • springboot注解@Order的使用

    使用order属性 设置该类在spring容器中的加载顺序 例如有三个类 Order1 Order2 Order3 其中Order1类如下 Component 把类交给spring容器管理 Order 1 使用order属性 设置该类在sp

随机推荐

  • scanf函数返回值的具体应用

    scanf函数返回值的具体应用 include
  • 小程序动态图片加载失败替换本地图片

    希望效果图 前言 写一个新闻列表 一个页面里就有几十条数据 虽然分页查询 但图片有时候还会加载失败 网速 图片大小等原因 下面说说我的思路 我把新闻列表封装成了一个子组件 1 在子组件标签image中放入error事件 传入index 2
  • 华为8年软件测试工程师感悟 功能测试如何体现自己的价值?

    无论在那个行业都有新人 而每个新人在刚入行时都会经历迷茫到精进的过程 大多数的测试人员也是如此 毕竟谁也不是一开始就是行业大佬 接下来 针对题主提出的问题以及描述的所处情况给大家讲一讲测试新人入行初期如何去摆脱迷茫做好自我提升 PS 这里有
  • Linux学习(十):查看文件系统(dumpe2fs)

    b 列出保留为坏道的部分 一般用不到 h 仅列出superblock的数据 不会列出其他的区块内容 1 找出我的根目录磁盘文件名 并查看文件系统的相关信息 ps df 调出目前挂载的设备 ps Filesystem volume name
  • suse linux下修复文件系统,Suse 11 下一次文件系统修复的案例 .

    操作系统 Suse Linux 11 文件系统 ext3 错误现象 X日 接到告警 检查文件系统 dev sda1发现写入报只读 检查IP存储有告警 随即umount img 但卸载后无法正常挂载 fdisk l显示IO错误 重启应用服务器
  • 如何判断文件是否读到文件结尾

    二进制文件 头文件 include define feof stream stream gt flag IOEOF feof 函数用来检测当前文件流上的文件结束标识 判断是否读到了文件结尾 其原型为 int feof FILE stream
  • 1. Ubuntu 20.04 初始化root密码

    1 以普通用户登录系统 创建root用户的密码 在终端输入命令 sudo passwd root 然后输入设置的密码 输入两次 这样就完成了设置root用户密码了 注意Linux系统下密码是没有回显的
  • servlet.Ajax实现上传文件进度条

    这里关于servlet如何上传文件就先不说了 将如何得到已经上传的文件数据的百分比 首先我们先写一个类这个类要实现ProgressListener这个接口 实现里面的update 方法 代码如下 package com test servl
  • 关于使用2d照片进行3d建模

    转载感言 作者一句业余 搞得弟兄们面红耳赤了 感谢作者的可行性分析 Autodesk 的 123D Catch 让我们能够很简单的根据一组照片构建3D物体 你只需要从各个角度拍摄希望建模的物体 然后通过 123D Catch 将照片上传到
  • Git拒绝在变基上合并不相关的历史

    问 在 git rebase origin development 期间 Git 显示以下错误消息 fatal refusing to merge unrelated histories Error redoing merge 1234de
  • TrainingOperator--PyTorchJob实现机制分析

    前言 由 Pytorch分布式训练 一 chenxy02的博客 CSDN博客 可知Pytorch分布式训练实现进程间寻址 主要依靠以下 四个参数 MASTER ADDR MASTER PORT WORLD SIZE RANK MASTER
  • ardupilot开发 --- 避障篇

    避障的类型 空中防碰撞ADSB 主要是防止与其他飞行器的碰撞 避障 防止与天花板地板障碍物的碰撞 实现避障必要的传感器 ADSB receivers Rangefinders or Proximity Sensors or Realsens
  • 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中最后一个单词的长度。

    提示 题目答案均由博主自主编写 想法不一 答案也不一 本答案仅提供参考 如有疑问 可在评论区提问 有时间会解答 题目描述 给你一个字符串 s 由若干单词组成 单词前后用一些空格字符隔开 返回字符串中最后一个单词的长度 单词是指仅由字母组成
  • 用python语言判断素数(质数)

    今天查了很多关于判断质数的代码 自己也尝试写了一下 质数是指在大于1的自然数中 除了1和它本身以外不再有其他因数的自然数 所有我们能很容易的想到使用for循环来实现输入数m和 2 m 1 的相除 代码实现 m eval input 请输入一
  • web服务器接口文档,接口文档

    有字库接口文档 由于中文字体文件过大 有字库采用 按需截取 根据页面内容把字体中不需要的字型删除掉 的方案 将中文字体压缩成和英文字体一样小巧玲珑 按需截取 与 整套嵌入 方案相比 1 按需截取 生成的中文字体只有十几K至一百多K 而 整套
  • 关于测试的静态方法学习笔记

    在学习软件测试时的一些笔记 可以加深对测试的理解 静态测试技术概述 1 静态测试是不执行被分析的程序 而是通过对模块源代码进行研读 找出其中的错误或可疑之处 收集一些度量数据 2 静态测试包括对软件产品的需求和设计规格说明书的评审 对程序代
  • docker安装wordpress

    参考文章 步骤 1 安装docker 2 下载wordpress镜像 3 下载mysql镜像 4 启动mysql容器 5 启动wordpress容器 遇到的问题 1 进入wordpress报数据库错误 猜测是连不上数据库 在宿主机尝试连接M
  • Qt on Android 之设置应用名为中文

    今早群里有个盆友问如何将 Qt 开发的 Android 应用的名字设置为中文 试验了一下 有两个办法 直接修改 AndroidManifest xml 文件 首先你在创建 Qt on Android 工程时需要创建一个 AndroidMan
  • Gmail,Qmail,163等邮件服务器SMTP、IMAP、POP3、地址及SSL/非SSL协议端口号

    最近项目需要给后台发送邮件 将项目中部分信息与后台同步 于是就有了这篇博客 以下的内容是参考网上的例子加上自己实践总结了一下 邮箱默认配置 服务器名称 服务器地址 SSL协议端口号 非SSL协议端口号 IMAP imap xx com 99
  • WebService客户端几种实现方式

    文章目录 一 发布一个webservice服务 jdk原生 1 编写服务接口 2 服务实现类 3 发布服务 4 浏览器查看是否发布成功 二 几种客户端调用方式 1 jdk原生调用 需要获取服务接口文件 2 用import命令生成客户端代码