java对接webservice接口的四种方式

news2024/10/2 16:22:03

这两天一直在做外系统对接,对方的接口是webservice的形式,调用起来有些蛋疼,于是在这里记录一下我尝试过的调用WebService的三种方式。

方式一:以HttpURLConnection的方式调用

			String url ="http://127.0.0.1/cwbase/Service/hndg/Hello.asmx?wsdl";
			URL realURL = new URL(url);
			HttpURLConnection connection = (HttpURLConnection) realURL.openConnection();
			connection.setDoOutput(true);
			connection.setDoInput(true);
			connection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
			connection.setRequestProperty("content-length",String.valueOf(xmlData.length));
			connection.setRequestMethod("POST");
			DataOutputStream printOut = new DataOutputStream(connection.getOutputStream());
			printOut.write(xmlOutString.getBytes("UTF-8"));//xmlOutString是自己拼接的xml,这种方式就是通过xml请求接口
			printOut.flush();
			printOut.close();
			// 从连接的输入流中取得回执信息
			InputStream inputStream = connection.getInputStream(); 
			InputStreamReader isr = new InputStreamReader(inputStream,"UTF-8");
			BufferedReader bufreader = new BufferedReader(isr); 
			String xmlString = ""; 
			int c;
			while ((c = bufreader.read()) != -1) { 
				 xmlString += (char) c; } 
			isr.close();
			//处理返回的xml信息
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document d = db.parse(new ByteArrayInputStream(xmlString.getBytes("UTF-8")));
			//从对方的节点中取的返回值(节点名由对方接口指定)
			String returnState = d.getElementsByTagName("ReturnStatus").item(0).getFirstChild().getNodeValue();

方式二:使用apache-cxf生成java类调用

下载apache-cxf并配置环境变量(参照JAVA环境变量配置),配置成功后cmd输入wsdl2java -help即可验证是否成功。
接着在cmd中输入wsdl2java -encoding utf-8 -d 生成路径 接口地址,即可在指定路径生成接口JAVA文件,生成后的JAVA类如下图:
在这里插入图片描述

生成以后调用起来就很简单了,例子如下:

		String result = "";
		NC65To63ProjectService service = new NC65To63ProjectService();
		NC65To63ProjectServicePortType servicePort =service.
				getNC65To63ProjectServiceSOAP11PortHttp(); 
		result = servicePort.receiptProject(json);

方式三:使用AXIS调用WebService

为了避免找不到对方包,所以我直接把包贴在顶上了。

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

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

		String result = "";
		String url = "http://127.0.0.1/uapws/service/nc65to63projectsysplugin";//这是接口地址,注意去掉.wsdl,否则会报错
		Service service = new Service();
		Call call = (Call) service.createCall();
		call.setTargetEndpointAddress(url);
		String parametersName = "string";//设置参数名
		call.setOperationName("receiptProject");//设置方法名
		call.addParameter(parametersName, XMLType.XSD_STRING, ParameterMode.IN);//方法参数,1参数名、2参数类型、3.入参
		call.setReturnType(XMLType.XSD_STRING);//返回类型
		String str = json;
		Object resultObject = call.invoke(new Object[] { str });//调用接口
		result = (String) resultObject;

方式四:试用httpclient

public static void main(String args[]) { 
// 第一种方法 ----------------------------------------------
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
		// 创建客户端连接
		Client client = factory.createClient("http://127.0.0.1:8080/xx/service/userOrg?wsdl");
		Object[] res = null;
		try {
			QName operationName = new QName("http://impl.webservice.userorg.com/","findUser");//如果有命名空间需要加上这个,第一个参数为命名空间名称,调用的方法名称
			res = client.invoke(operationName, "admin");//后面为WebService请求参数数组
			System.out.println(res[0]);
		}catch (Exception e) {
			e.printStackTrace();
		}

 // 第二种方法 ----------------------------------------------
// 被<![CDATA[]]>这个标记所包含的内容将表示为纯文本 
String xmlData = "<![CDATA[<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
"<accounts>" + 
"<account>" + 
"<accId>帐号ID(必填)</accId>" + 
"<userPasswordMD5>密码</userPasswordMD5>" + 
"<userPasswordSHA1>密码</userPasswordSHA1>" + 
"其中userPasswordSHA1标签代表SHA1加密后的密码,userPasswordMD5标签代表MD5加密后的密码" + 
"<name>姓名</name>" + 
"<sn>姓</sn>" + 
"<description>描述 </description>" + 
"<email>邮箱 </email>" + 
"<gender>性别</gender>" + 
"<telephoneNumber>电话号码</telephoneNumber>" + 
"<mobile>移动电话</mobile>" + 
"<startTime>用户的开始生效时间(YYYY-MM-DD HH:mm:SS)</startTime>" + 
"<endTime>用户结束生效时间(YYYY-MM-DD HH:mm:SS) </endTime>" + 
"<idCardNumber>身份证号码</idCardNumber>" + 
"<employeeNumber>工号 </employeeNumber>" + 
"<o>用户所属的组织的编码号 </o>" + 
"<employeeType>用户类型</employeeType>" + 
"<supporterCorpName>所在公司名称 </supporterCorpName>" + 
"</account>" + 
"</accounts>]]>";

//调用方法
String method = "sayHello";
   method = "getUserList";
   
String data="<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://impl.webservice.platform.hotent.com/\">"+
   "<soapenv:Body>"+
      "<ser:"+method+">"+
         "<arg0>"+ xmlData + "</arg0>"+
      "</ser:"+method+">"+
   "</soapenv:Body>"+
"</soapenv:Envelope>";
String httpUrl="http://127.0.0.1:8080/xx/service/helloWorld?wsdl";
   httpUrl="http://127.0.0.1:8080/xx/service/userOrg?wsdl";
try {
//第一步:创建服务地址  
   URL url = new URL(httpUrl);  
   //第二步:打开一个通向服务地址的连接  
   HttpURLConnection connection = (HttpURLConnection) url.openConnection();  
   //第三步:设置参数  
   //3.1发送方式设置:POST必须大写  
   connection.setRequestMethod("POST");  
   //3.2设置数据格式:content-type  
   connection.setRequestProperty("content-type", "text/xml;charset=utf-8");  
   //3.3设置输入输出,因为默认新创建的connection没有读写权限,  
   connection.setDoInput(true);  
   connection.setDoOutput(true);  

   //第四步:组织SOAP数据,发送请求  
   String soapXML = data;
   //将信息以流的方式发送出去
   // DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写到流里面
   
   OutputStream os = connection.getOutputStream();  
   os.write(soapXML.getBytes());  
   //第五步:接收服务端响应,打印  
   int responseCode = connection.getResponseCode();  
   System.out.println("responseCode: "+responseCode);
   if(200 == responseCode){//表示服务端响应成功  
   //获取当前连接请求返回的数据流
       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);  
       }  
       
       is.close();  
       isr.close();  
       br.close(); 
       System.out.println(StringEscapeUtils.unescapeXml(sb.toString()));    //转义
       System.out.println(sb.toString());  
       
    } else { //异常信息
   InputStream is = connection.getErrorStream();    //通过getErrorStream了解错误的详情,因为错误详情也以XML格式返回,因此也可以用JDOM来获取。  
   InputStreamReader isr = new InputStreamReader(is,"utf-8");  
   BufferedReader in = new BufferedReader(isr);  
   String inputLine;  
   BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(  
           new FileOutputStream("d:\\result.xml")));// 将结果存放的位置  
   while ((inputLine = in.readLine()) != null)   
   {  
       System.out.println(inputLine);  
       bw.write(inputLine);  
       bw.newLine();  
       bw.close();  
   }  
   in.close(); 
   }
   
   os.close(); 
} catch (Exception e) {
System.out.println(e.getMessage());
}
}

// 把xml转义
public static String escapeXml(String xml) {
String newXml = xml.replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll(" ", "&nbsp;").replaceAll("\"", "&quot;");
return newXml;
}

总结

第一种使用HttpURLConnection调用的方法,基本不用担心什么兼容问题,但是通过xml请求接口,需要自己手动拼接xml(一般通过soapui生成,然后在程序中根据情况拼接),并且返回的数据也是xml,还要通过代码解析,可以说是极其麻烦了。

另外,我在实际使用中,调用一个特殊接口时竟然没有返回正确结果,而是返回了wsdl文档,这一点我折腾了很久也没能找到原因,网上也有同样受到这个问题困扰的人,有知道的可以指点一二。
这是我在某博客下看到的回复:
在这里插入图片描述

第二种apache-cxf生成java类调用的方式,直接调用生成的类即可访问接口,非常方便,但是apache-cxf和jdk有兼容问题,如果关联的某个jar包中的代码有冲突,就会遇到痛苦的报错了。在我的尝试中,就有一个Service冲突的问题,网上说需要更改某jar包中的class文件,但是由于项目太过庞大,担心会触发其他的问题,所以我只能就此作罢。

重点来了,第三种AXIS的方式, 没有啥兼容问题的方式了,调用起来非常简便,不需要拼接xml,返回的也只能干净的数据,简直太赞了,如果你在工作中也有这方面的需要,我强烈建议你别折腾了,直接使用AXIS吧!

第四种:

httpclient本人亲测好用。不用引用cxf或AXIS一大堆jar包,比较方便

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/983215.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode】297.二叉树的序列化与反序列化

题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作&#xff0c;进而可以将转换后的数据存储在一个文件或者内存中&#xff0c;同时也可以通过网络传输到另一个计算机环境&#xff0c;采取相反方式重构得到原数据。 请设计一个算法来实现二叉树的序列化与反序列化…

百度智能云千帆大模型丨未来人手必备的代码助手

文章目录 1. 前言2. 千帆大模型平台3. 十分友好的功能4. comate代码助手5. 总结 1. 前言 我之前给大家推荐过Poe这个网站&#xff0c;它用的人比较少&#xff0c;但一旦接触后会发现它其实挺强大的。 因为它是一个可以同时支持好几个大模型的在线聚合平台。常用的GPT4&#x…

idea:java: Compilation failed: internal java compiler error

java: Compilation failed: internal java compiler error错误 检查下面2个即可&#xff1a;

智能转码技巧大揭秘,轻松实现视频转码!

你是否曾经遇到过需要将视频进行转码&#xff0c;但却被繁琐的步骤和复杂的参数困扰&#xff1f;现在&#xff0c;我们教你如何巧用智能转码&#xff0c;让视频转码变得轻松简单&#xff01; 首先第一步&#xff0c;我们要进入媒体梦工厂主页面&#xff0c;在板块栏里选择“智…

Debian11安装Geoserver+矢量插件Vector Tiles

呕心之作&#xff0c;小白教程 1 安装 Java 112 安装Geoserver2.1 安装2.2 设置自启动2.3 跨域问题 3 安装矢量插件 Geoserver的官网安装手册。 GeoServer需要 Java 8 或者 Java 11 环境 1 安装 Java 11 Debain默认安装 Java 11 版本&#xff0c;直接执行&#xff1a; # 确认…

保姆级别redis安装轻轻松松上手使用

Redis安装 Windows快速安装安装包下载安装 Windows快速安装 安装包下载 https://github.com/microsoftarchive/redis/tags安装 直接运行.msi的安装包&#xff0c;一直next&#xff0c;直到下面界面,勾选上再next 最后点击finish 进入计算机服务中(右键计算机–>管理–…

无涯教程-JavaScript - WORKDAY.INTL函数

描述 WORKDAY.INTL函数返回带有自定义周末参数的指定工作日数之前或之后的日期的序列号。周末参数指示哪些和多少天是周末。周末和指定为假期的任何日子均不视为工作日。 语法 WORKDAY.INTL (start_date, days, [weekend], [holidays])争论 Argument描述Required/OptionalS…

CVE-2023-35843:NocoDB任意文件读取漏洞复现

文章目录 NocoDB 存在任意文件读取漏洞CVE-2023-358430x01 前言0x02 漏洞描述0x03 影响范围0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06修复建议 NocoDB 存在任意文件读取漏洞CVE-2023-35843 0x01 前言 本次测试仅供学习使用&#xff0c;如若非法他用&…

VMware 安装 黑群晖7.1.1-42962 DS918+

本例的用的文件 1、ARPL 1.0beat 引导文件 vmdk格式&#xff1a; https://download.csdn.net/download/mshxuyi/88309308 2、DS918_42962.pat&#xff1a;https://download.csdn.net/download/mshxuyi/88309383 一、引导文件 1、创建一个虚拟机 2、下一步&#xff0c;选稍后…

Grad-CAM,即梯度加权类激活映射 (Gradient-weighted Class Activation Mapping)

Grad-CAM&#xff0c;即梯度加权类激活映射 (Gradient-weighted Class Activation Mapping)&#xff0c;是一种用于解释卷积神经网络决策的方法。它通过可视化模型对于给定输入的关注区域来提供洞察。 原理: Grad-CAM的关键思想是将输出类别的梯度&#xff08;相对于特定卷积…

初阶三子棋(超详解)

✨博客主页&#xff1a;小钱编程成长记 &#x1f388;博客专栏&#xff1a;C语言小游戏 初阶三子棋 1.游戏介绍2.基本思路3.实现前的准备4.实现步骤4.1 打印菜单4.2 初始化棋盘4.3 打印棋盘4.4 玩家下棋4.5 电脑下棋4.6 判断本局游戏继续还是结束4.7 优化棋盘的显示 5.游戏代码…

汽车技术发展趋势及我国节能与新能源汽车技术

一、世界汽车技术发展趋势 汽车技术正向着低碳化、信息化、智能化方向发展&#xff1b;“三化”趋势成为世界主要汽车强国、主要车企共同的战略选择。 主要汽车战略及方向 在“三化”趋势下&#xff0c;各汽车强国在汽车节能技术、新能源汽车技术、智能网联汽车技术等方面持续…

算法训练营day42|动态规划 part04:0-1背包 (01背包问题基础(两种解决方案)、LeetCode 416.分割等和子集)

文章目录 01背包----二维dp数组01背包----滚动数组416.分割等和子集思路分析背包解法思考总结 有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最…

深入解析Spring Boot中最常用注解的使用方式(下篇)

摘要&#xff1a;本文是《深入解析Spring Boot中最常用注解的使用方式》的下篇内容&#xff0c;将继续介绍Spring Boot中其他常用的注解的使用方式&#xff0c;并通过代码示例进行说明&#xff0c;帮助读者更好地理解和运用Spring Boot框架。 目录 第二部分&#xff1a;常见的容…

浏览器开发者模式下只显示 XHR 请求应该怎么办

浏览器开发者模式下只显示 XHR 请求应该怎么办 问题分析 问题 F12打开浏览器的开发者模式&#xff0c;然后点击 Network&#xff0c;只显示 XHR 请求应该怎么办 分析 打开漏斗&#xff0c;选择All 模式

怎么给视频加背景音乐?学会这三种方法轻松配乐

给视频添加配乐可以带来多重好处。首先&#xff0c;配乐可以增强视频的氛围和情感&#xff0c;帮助观众更好地投入其中&#xff0c;感受视频所要表达的情感。不同的音乐可以传达不同的情感&#xff0c;例如悲伤、欢乐、紧张等等&#xff0c;可以让观众更深入地体验视频内容。教…

2023年9月NPDP产品经理国际认证报名,找弘博创新

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

vue响应式原理

vue响应式原理 vue响应式原理vue2响应式原理目标对象为数组时 vue3响应式原理Vue3和Vue2在响应式系统方面的对比数据劫持的方式支持数据劫持的数据类型Vue3响应式系统显著优点是&#xff1a; vue响应式原理 无论vue2和vue3响应式都是通过观察者模式&#xff08;发布订阅模式&a…

技术分享 | 强化学习,让机器像人类一样自我学习

如果说近年来有什么是各行各业共通的话题&#xff0c;那就一定是强化学习&#xff0c;这是一个让机器能够像人类一样通过与环境互动来学习和改进自己决策的领域。它不仅令人兴奋&#xff0c;而且具有革命性的潜力&#xff0c;可以改变我们生活和工作的方式。 随着计算能力的不断…

perf与simpleperf

对事件进行采样&#xff0c;然后根据采样频率&#xff0c;评估各个函数的调用频率。可以用来分析CPU cache&#xff0c;CPU迁移&#xff0c;指令周期等各种硬件事件&#xff0c;他也可以对感兴趣的事件进行动态追踪。 效果&#xff1a; cat available_events | grep receive p…