我的第一次Webservice接口开发

转:

我的第一次Webservice接口开发

我的第一次Webservice接口开发
原创 jianhaojiang 最后发布于2019-05-09 16:58:09 阅读数 9830 收藏
展开
前言

最近项目上需要对接WebService接口,之前从来没有用过,这次都遇见了。记录下基础的使用和我遇见的问题。
正文
概述

WebService接口百度一搜,各个介绍的都非常详细,由于刚开始没接触,看的也不是很懂。首先记住一句话:WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
跨编程语言和跨操作系统平台:也就是说Asp.net开发的WebService我用java代码调用完全没问题,和操作系统也没有关系。
远程调用技术:也就是说网络是通的就能用。
那么这个WebService到底是干嘛用的?
作用

对接呗!比如我现在需要使用第三方公司的短信服务,使用WebService来调用它的服务为我所用,只需要第三方公司提供一个接口调用文档和WebService地址,我就能根据文档地址编程去调用它为我开放的短信服务,发送短信。为什么是WebService?
优缺点

回到那句话,WebService是一种跨编程语言和跨操作系统平台的远程调用技术。
优点:
1.跨语言和跨操作系统:因为WevService是通过Xml语言进行描述的,XML主要的优点在于它既与平台无关,又与厂商无关。
2.远程调用技术:不用担心防火墙的问题。。。
缺点:
1.服务端接口方为webservice则客户端也必须使用webservice。
2.因为webservice使用xml传输数据,因此性能上不能满足高并发。
3.有点笨重。。。
其实WebService并不是非常流行,往往RESTful就能够达到需要,但是遇到了笔记还是要做的。
使用

只介绍对接WebService接口,生成请自行百度。
我这次对接了java的WebService接口和C#写的WebService接口。
CXF 调用java WebService

首先我们看看提供的WebService接口地址:http://127.0.0.1:8080/jjh/webService/smsXXX?wsdl
一般都是给到这找种地址,我们访问地址可以看到这个接口的xml描述,我们可以通过这个描述来生成java代码到本地来方便我们的使用,比如一些实体类,service方法。
准确的来说我们可以使用JDK自带的和CXF提供的命令,直接生成java代码,这里只建议使用Apach的CXF,直接去官网下载最新的cxf包,进入bin目录下,打开命令窗口,使用cxf命令生成java代码,这里提供一个最基础的:wsdl2java -encoding utf-8 http://127.0.0.1:8080/jjh/webService/smsXXX?wsdl
执行之后你的bin目录下面会生成java文件,有了java文件下面就可以根据java文件和第三方给的文档进行调用了。
比如,生成了IhalloWorld.java和IService.java文件,发现IhalloWorld接口里面声明了sendSms(args…)方法。

public static void main(String[] args) {  
        JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();  
        //要得到的对象,是根据本地IService 接口取得的。
        factoryBean.setServiceClass(IService .class);  
        //调用地址
        factoryBean.setAddress("http://127.0.0.1:8080/jjh/webService/smsXXX");  
        //通过webservice取到IService的实现类,这个实现类才是你真正想要的,里面包括了你需要的东西。
        IService service = (IService)factoryBean.create();  
        IhalloWorld hello = service.getHelloWorld("xxx");  
        System.out.println("Hello:"+hello.sendSms("XXX你好..."));  
    }

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

参考链接:
JAVA webservice之CXF
WebService学习整理-JDK的wsimport命令和cxf的wsdl2java命令的区别和使用
java接口调用——webservice就是一个RPC而已
cxf的wsdl2java命令和JDK的wsimport命令的区别和使用
asmx

下面又对接了一个C#写的WebService接口,比如链接为:http://127.0.0.1:81/WebServiceCS/service.asmx ,在这个链接后面加上?wsdl,即:
http://127.0.0.1:81/WebServiceCS/service.asmx?wsdl 也是可以使用cxf生成java代码的,但是注意一点,这接口是C#写的,xml只描述出实体信息,生成类似实体类的文件,不想上面一样直接有现成的接口使用。一般其实也用不到cxf来生成,作用不大。参考例子:

public String sendMail(Object[] params) {
    String soapaction = "http://tempuri.org/"; // 域名,这是在server定义的,在链接里面看得到,下面介绍。
    String operationName = "Mail_Send";// 调用服务名
    Service service = new Service();
    String ret = "";
    try {
        Call call = (Call) service.createCall();
        call.setTargetEndpointAddress(url);
        call.setOperationName(new QName(soapaction, operationName)); // 设置要调用的方法
        call.addParameter(new QName(soapaction, "vvvv"), // 需要传递的参数名
                org.apache.axis.encoding.XMLType.XSD_STRING,
                javax.xml.rpc.ParameterMode.IN);
        call.addParameter(new QName(soapaction, "jjj"), // 需要传递的参数名
                org.apache.axis.encoding.XMLType.XSD_STRING,
                javax.xml.rpc.ParameterMode.IN);
        call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// (标准的返回类型)
        call.setUseSOAPAction(true);
        call.setSOAPActionURI(soapaction + operationName);//url,域名加方法名
        ret = (String) call.invoke(params);// 调用方法并传递参数,params包含参数
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    return ret;
}

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

其中operationName服务名和soapaction域名都在你的链接中可以找到 http://127.0.0.1:81/WebServiceCS/service.asmx
在这里插入图片描述
其中参数params数组根据你服务需要的参数来传,比如需要一个规范的xml字符串作为参数,使用dom4j进行操作。

Document doc = DocumentHelper.createDocument();
        //增加根节点
        Element books = doc.addElement("books");
        //增加子元素
        Element book1 = books.addElement("book");
        Element title1 = book1.addElement("title");
        Element author1 = book1.addElement("author");

Element book2 = books.addElement("book");
        Element title2 = book2.addElement("title");
        Element author2 = book2.addElement("author");

//为子节点添加属性
        book1.addAttribute("id", "001");
        //为元素添加内容
        title1.setText("Harry Potter");
        author1.setText("J K. Rowling");

book2.addAttribute("id", "002");
        title2.setText("Learning XML");
        author2.setText("Erik T. Ray");

OutputFormat format = OutputFormat.createCompactFormat();
        format.setIndent(true); //设置是否缩进
        format.setIndent("    "); //以四个空格方式实现缩进
        format.setNewlines(true); //设置是否换行

//设置输出编码
        format.setEncoding("gb2312");
        StringWriter writer = new StringWriter();
        XMLWriter output = new XMLWriter(writer, format);
        try {
            output.write(doc);
            writer.close();
            output.close();
            System.out.println(writer.toString());//打印xml字符串
        }  catch (IOException e) {
            e.printStackTrace();
        }

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

打印结果
在这里插入图片描述

参考链接:
Java调用webservice的.asmx后缀接口
java调用webservice接口(.asmx)
遇见的问题

说实话开发起来挺快的,毕竟人家提供接口,东西都是现成的,最要命的问题就是报错了。
导包

包没导好,错少不了,可以参考这个博主的包导一导试试java调用webservice接口(.asmx),遇见报错不要慌,参考一下这个解决:WebService几个常见的异常
我这里遇到的一个问题就是:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.axis.client.AxisClient
我是由于commons-logging.jar包依赖版本冲突导致的,commons-discovery.jar包里面依赖了commons-logging包,但是,我自己导了commons-logging包,我的解决是排查commons-discovery对commons-logging的依赖:

<dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.5</version>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

参考的java.lang.NoClassDefFoundError博客。
接下来我又遇见了新的问题,弄了很久:由于我上面用了CXF,引入了一些包和我现在调.asmx接口axis2引入包又版本冲突了,,,,这个真的没找到,项目一调用CXF的那个接口就报错:
java.lang.RuntimeException: Cannot create a secure XMLInputFactory
网上找了找解决办法:
1.有说缺少包,导入woodstox-core-asl-4.4.1.jar和stax2-api-3.1.4.jar包。
2.woodstox-core-asl包需要优先被加载,修改tomcat下,这个包在lib文件夹的名字,因为tomcat是按顺序来加载的,woodstox-core-asl改名为awoodstox-core-asl,让它优先加载。
参考:
解决 调用报错: “Cannot create a secure XMLInputFactory”
java.lang.RuntimeException: Cannot create a secure XMLInputFactory解决方案

但是,上面两个都没解决我的问题,我感觉原因还是版本冲突了,,,
最后我找到了一个解决方法:
CXF报安全性错误 Cannot create a secure XMLInputFactory
大佬就是大佬,然后我就调用之前添加了这行代码:

System.setProperty(StaxUtils.ALLOW_INSECURE_PARSER, "true");

1

完美,但是这个版本冲突估计是没救了,依赖太多了。
idea插件没解决掉,然后查看maven依赖树来解决:
我以为的maven依赖图是这样的(一览无余):
在这里插入图片描述
实际上是这样的:
在这里插入图片描述
对不起,一览无余,打扰了。。。能力有限,版本冲突我干不掉了。
之前组长是建议我添加一个简单的web项目,里面只部署CXF 对接的接口供我项目调用,这样两个接口依赖的包就不会在一块有版本冲突了,我觉得这个方法还是很赞的!!!
后续

后面项目部署到tomcat上面,发现jar包还是冲突啦!!!
大概错误就是这样

Caused by: java.lang.NoSuchFieldError: REFLECTION

at com.sun.xml.bind.v2.model.impl.RuntimeModelBuilder.<init>(RuntimeModelBuilder.java:43)
 
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:344)
 
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:216)
 
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76)
 
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55)
 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 
at java.lang.reflect.Method.invoke(Method.java:498)
 
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:247)
 
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:234)
 
at javax.xml.bind.ContextFinder.find(ContextFinder.java:441)
 
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:641)
 
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:584)

1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

一番搜索后参照:
stackoverflow
java.lang.NoSuchFieldError: REFLECTION
发现是com.sun.xml.bind:jaxb-core和com.sun.xml.bind:jaxb-impl****两个包版本号不一致造成的冲突。首先查看jar包的依赖情况,使用idea查看依赖树,运行maven命令 mvn dependency:tree。
在这里插入图片描述
不使用idea也一样,在pom文件位置打开cmd面板,如下图,在路径处输入cmd回车,执行maven命令 mvn dependency:tree。
在这里插入图片描述
查看jar包依赖情况:
在这里插入图片描述
在这里插入图片描述
分别搜索jaxb-impl和jaxb-core,发现它们是jar包axis2-jaxws和cxf-rt-frontend-jaxws分别依赖的子包。版本号分别是2.1.7和2.2.11,我这里是取消了axis2-jaxws对jaxb-impl的依赖,单独配置jaxb-impl的依赖,指定版本号和jaxb-core一致2.2.11。
在这里插入图片描述
最后将打包后的jaxb相关包替换在tomcat的包,使得版本一致,到此版本冲突问题解决。
参考地址集合

JAVA webservice之CXF
WebService学习整理-JDK的wsimport命令和cxf的wsdl2java命令的区别和使用
java接口调用——webservice就是一个RPC而已
cxf的wsdl2java命令和JDK的wsimport命令的区别和使用

Java调用webservice的.asmx后缀接口
java调用webservice接口(.asmx)

WebService几个常见的异常
java.lang.NoClassDefFoundError

解决 调用报错: “Cannot create a secure XMLInputFactory”
java.lang.RuntimeException: Cannot create a secure XMLInputFactory解决方案

CXF报安全性错误 Cannot create a secure XMLInputFactory

stackoverflow
java.lang.NoSuchFieldError: REFLECTION
maven dependency:tree中反斜杠的含义
如何查看Maven项目中的jar包依赖树情况?

点赞 4
    收藏
    分享

————————————————
版权声明:本文为CSDN博主「jianhaojiang」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_38584967/java/article/details/90040429

原文地址:https://www.cnblogs.com/libin6505/p/12665029.html

时间: 2024-11-05 18:47:07

我的第一次Webservice接口开发的相关文章

基于Axis1.4的webservice接口开发(代码开发)

一.开发环境: 我的开发环境是MyEclipse 2015+Apache-Tomcat-8.0.21. 二.代码开发: 1.新建一个Web Project工程,并导入jar包(Axis1.4的环境搭建在上一篇博客http://www.cnblogs.com/zhukunqiang/p/7124977.html中有介绍): 1.在com.ll.server包下新建java类,工程结构目录如下: 2.java代码如下(由于该项目用于测试,简单点无所谓): package com.ll.server;

首次使用Restful进行webservice接口开发小结

所写内容根据自身项目而定 1.安装,web请求测试插件 postman 下载插件包:postman 4.2.7.zip 打开 google的 chrome 浏览器 设置 --> 扩展程序 --> 加载已解压的扩展程序, 如下图: 安装完成后:在地址栏里输入:chrome://apps,点击postman, restClient 2.第二步利用 postman测试,发送web请求. 背景:利用restful作为webservice开发接口,接口开发完毕,进行测试 接口如下:请求格式,响应格式都是

基于Axis1.4的webservice接口开发(接口调用)

一.webservice接口代码参考上一篇博客: http://www.cnblogs.com/zhukunqiang/p/7125668.html 二.代码部分 1.新建Web Project工程,取名为axiswebserviceClint,并导入Axis1.4所需jar包(将jar包粘贴到lib目录). 2.新建webservice接口调用类: package com.no8.clint; import java.net.URL; import javax.xml.rpc.ServiceE

WebService接口开发

Web Service 元数据注释(JSR 181) @WebService 1.serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service.缺省值为 Java 类的简单名称 + Service.(字符串) 2.endpointInterface: 服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口 3.name:此属性的值包含XML Web Service的名称.在默认情况下,该值是实现XML

EJBCA开发 webService接口调用

<转载请注明出处> 摸索这个东西好长时间了,资料太少无从下手找了个EJBCA的类似论坛的东西 一点点找入口..... 分享下:http://sourceforge.net/p/ejbca/discussion/132019/,有问题 里面的人很快会回答的,但是 他们是做盈利机构的有些问题.. EJBCA SVN路径:https://svn.cesecore.eu/svn/ejbca/tags/Rel_3_9_7/ejbca   这是3的版本 有其他的自己找吧. 一.先介绍下接口调用: EJBC

利用MyEclipse开发一个webservice接口

一直以来对于接口这个东西都很好奇,各种客户也一直在说那个什么什么数据我们提供给你们一个接口就好了,结果还是不是很明白.于是乎就有了下面的小故事,接下来我们就进入正文吧 ---大概可以分为这样的步骤 1:新建webservice project,Framework版本选择JAX-WS 2:编写测试类,写一个简单的AddUser方法 3:在webservice project 上面 new webservice 确定后,在project和接口主类同一目录会生成一个Delegate.Java 4:加入

使用cxf开发webservice接口

项目中经常用到开发webservice接口,及调用webService接口.这里讲解如何使用cxf开发webService接口. 一.webservice介绍及理解 webservice是一种跨平台,跨语言的规范,用于不同平台,不同语言开发的应用之间的交互.        比如,平台平台淘宝.京东想获取其他快递公司数据接口,需快递公司开放数据接口.       那么 webservice就是出于以上类似需求而定义出来的规范:无需关心对方什么平台上开发以及使用何种语言开发.       只关心调用

利用MyEclipse开发一个调用webservice接口的程序

上一篇文章我们已经学习了如何使用Java 工具MyEclipse开发一个webservice接口,那么接口开发好了如何调用?接下来我们就来解决这个问题. 1:首先随便创建一个Java project选中--New  Webservice Client 2:选中JAX-WS,下一步 3:在WSDL URL里面写入接口的测试地址 ↓接下来WSDL VAlidation竟然报错了,如何解决请往下看 把localhost换位主机IP地址 下一步 ,OK 通过通过验证 客户端会默认给我们选中需要导入的包

webservice接口的开发和调用

一.开发webservice接口的方式 1.使用jdk开发 2.使用第三方工具,如cxf.shiro等 二.使用jdk开发webservice接口以及调用 首先定义一个天气预报的接口,Weather @WebService public interface Weather { String queryWeather(); } 定义一个实现类,实现该接口 @WebService public class WeatherImpl implements Weather{ public String q