学习CXF WebService入门实例一
- 格式:doc
- 大小:108.00 KB
- 文档页数:7
用CXF开发RESTful风格WebService目录1RESTful简要介绍 (1)2开发一个普通的接口 (1)2.1定义DTO (1)2.2定义接口 (2)2.3实现类 (2)3开发RESTful风格WebService服务端 (2)3.1定义资源(定义DTO) (2)3.2开发接口 (3)3.3实现类 (4)3.4配置CXF(整合Spring) (4)3.4.1接口的Spring配置文件 (4)3.4.2CXF的Spring配置文件 (4)3.4.3修改web.xml (5)4开发RESTful风格WebService客户端(Java) (5)4.1定义客户端接口 (5)4.2定义实现类 (6)1RESTful简要介绍RESTful风格的WebService之所以当下如此流行,是由于其相对于SOAP风格的WebService 更简洁、更轻量级,REST风格的WebService传输的是JSON或极其简洁的XML,因而其效率和性能都比较理想。
RESTful风格的WebService主张重用HTTP协议,面向资源编程(ROA)。
扼要的说,RESTful 风格WebService中,每一个URL即表示一个资源,比如/employees/1表示id为1的员工。
1.如果对此URL调用HTTP GET方法,则返回员工的XML形式;2.如果对此URL调用HTTP POST/PUT方法,则可以新增或者修改此员工;3.如果对此URL调用HTTP DELETE方法,则可以删除此员工;因此,我们在设计一个RESTful风格的接口时,一定要拥有面向资源设计的考量!此外,在实现接口的过程中,要遵循RESTful风格的几个特性,他们分别是:1.无状态性:HTTP本身即是无状态协议,因此RESTful天然的具备无状态性,具备优良的水平扩展能力!2.幂等性:GET/PUT/DELETE方法具备此特性,幂等性可概述为无论重复调用多少次,其结果都一致!POST例外,不过设计的时候也可以按照此特性设计!3.唯一性:即URL地址要唯一的表示一个资源!关于事务、安全等更多的高级特性这里不阐述,有兴趣的可参考《Restful Web Service中文版》一书。
/docs/index.html/注意,在非java-project中,例如在web-project中可能出现(activation.jar和mail.jar)与工程中的j2ee.jar以及myeclipse中D:\MyEclipse 5.5.1 GA\myeclipse\eclipse\plugins\com.genuitec.eclipse.j2eedt.core_5.5.1\data\libraryset\EE_5的javaee.jar里面的同名包发生冲突,建议把j2ee.jar和javaee.jar中的同名包删除,或者直接使用J2ee.jar把eclipse自带的javaee.jar从工程中去除并加入相应的包1.WSDL2JA V A生成客户端代码2.JAXB3.JAX-WS4.WS-Addressing5.WS-Policy6.WS-Security7.webservice 注释8.拦截器WSDL2JA V A生成客户端代码CXF支持代码生成1)Java to WSDL 、2)WSDL to Java 、3)XSD to WSDL 、4)WSDL to XML5)WSDL to SOAP 、6)WSDL to service如下:D:\apache-cxf-2.2.5\bin>wsdl2java -d d:/cxf-client -p example1.client http://127.0.0.1:8080/ws/HelloWorld?wsdlJAXB/group/10141/topic/12028CXF默认的数据绑定使用的JAXB,XFIRE使用Aegis替代数据绑定就是把java对象转化为xml和把xml文件转化为java对象不管使用任何的XML解析代码库(dom4j等),对于xml只是一个解析工作而已,不能马上绑定到java 对象。
对于对象,每次都需要set 或者get相应的属性,当然也可以使用map 来保存xml配置。
首先,我们必须了解什么是webservice.就概念上来说,可能比较复杂,不过我们可以有个宏观的了解:webservice就是个对外的接口,里面有函数可供外部客户调用(注意:里面同样有客户不可调用的函数).假若我们是服务端,我们写好了个webservice,然后把它给了客户(同时我们给了他们调用规则),客户就可以在从服务端获取信息时处于一个相对透明的状态.即是客户不了解(也不需要)其过程,他们只获取数据.webservice传递的数据只能是序列化的数据,典型的就是xml数据,这里我们也只讨论xml数据的传输.有了一些对xml webservice的初步了解后,我们将切入正题,即是用一个具体的webservice事例的形式来讲解具体的webservice用法,用具体的事例来讲解一个概念我想怎么也要比单纯的说理能让人容易理解吧.这里,我们将以一个简单的分布式课件搜索系统为例来讲解.使用VS2003为编译环境,C#为语言,SqlServcer2000为数据库.(这个例子来源于一位网上朋友的文章的启发,觉得很能代表webservice的特点,就按那个想法做了这么个系统来示例了)首先,明确我们要做什么.我们需要一个对客户的接口,也就是个站点,我们把它称做ServiceGatherSite,它是何种形式都无所谓,甚至它本身并不需要数据库,它只是提供给用户一个查询的接口,真正的服务,普通用户是不接触到的.然后,这里我们还需要若干个提供服务的站点,我们可以称它们为资源站,这里为简单起见,假设有两个资源站,分别叫WebSiteA,WebSiteB,它们可以是不对外公布的,只是为了丰富查询数据而存在.最后,是我们最需要关注的东西---资源站提供给ServiceGatherSite的服务.两个资源站,就有两个服务,我们称为SiteAService和SiteBService.两个服务间没有任何关系,内部提供的方法也完全没关联,只是需要把方法如何使用告诉ServiceGatherSite,意思是,服务只提供查询接口,返回的数据如何处理,服务本身并不管,全由使用服务的站点分配.写了这么多,算是简要的介绍了下有关xml webservice的概念和我们这个例子的结构,下篇文章,我们将开始真正进入代码的设计阶段.上篇文章介绍了些webservice的基本特性和我们例子的结构,这篇文章我们将开始具体的代码编写工作.这个专题主要讲述的是webservice,因此这里我们的代码以Webservice相关为主,而其他工程,例如:ServiceGatherSite,WebSiteA等,只将简略介绍.在VS2003中,开发一个webservice并不是件困难的事,首先,我们新建一个webservice 项目(文件->新建->项目->C#->Web服务应用程序)建完这个工程,我们将看到一个叫Service1.asmx的文件,这就是webservice的标准文件,它也有UI的概念,不过我们一般不关注,因此,我们查看其cs代码文件.如果你什么都还没做的话,将看见一个被注释掉的helloworld的WebMethod,把注释去掉,在运行,你就可以得到最简单的webservice运行实例了.点击"helloworld"将执行其方法.显然,这个函数对我们的意义只在于宏观的了解了下web服务的写法.下面,我们将开始具体介绍webservice的写法.在代码文件里,如果我们写了一个函数后,希望此函数成为外部可调用的接口函数,我们必须在函数上面添上一行代码[WebMethod(Description="函数的描述信息")],如果你的函数没有这个申明,它将不能被用户引用.如:[WebMethod(Description="最简单的方法")]public string HelloWorld(){return "Hello World";}这个函数就是外部可调用的接口函数,对用户来说相当于一个API.如果某用户在引用了这个服务后,他调用HelloWorld()方法,他就将获得"HelloWorld"这个返回值.看到这里,我们是不是发现,其实webservice并不是那么的神秘,它也不过只是个接口,对我们而言,侧重点依然是接口函数的编写.下面,我将给出我们的例子所需要的接口函数.[WebMethod(Description="查询以获取需要的课件信息")]public XmlDataDocument GetSiteAData(string AssignName){XmlDataDocument xd=new XmlDataDocument(); //DataSet ds=new DataSet();CStoreProc cp=new CStoreProc("SearchAssign");cp.AddParIn("@keywords",SqlDbType.VarChar,30,AssignName);cp.AddParOut("@res",SqlDbType.Int);if(cp.SelectProc()) //如果执行成功,存储过程{cp.myData.EnforceConstraints=false; //不进行格式严格检查if((int)cp.GetReturnValue("@res")==-1){string xml="<NewDataSet></NewDataSet>";xd.LoadXml(xml);return xd;}xd=new XmlDataDocument(cp.myData);XmlNode root1=xd.DocumentElement;XmlNodeList roots=root1.SelectNodes("list");foreach(XmlNode roota in roots) //为所有元素加上站点名称标记{XmlElement Link=xd.CreateElement("SiteName");Link.InnerText=ConfigurationSettings.AppSettings["SiteName"].ToString();roota.AppendChild(Link);}return xd;}else return null;}这是获取资源站点信息的一个接口函数.里面大部分的代码,我想对于有一定基础的朋友来说,都应该是一看就明白,这里只说明下CStoreProc,这是我封装的一个存储过程类,主要功能是执行各种类型的存储过程.细心的朋友可能会发现这个函数的返回类型似乎比较特殊,是个xml的文档.我们在前面已经说过,webservice只能传输序列化数据,xml显然满足条件,但比如hash表之类的非序列化数据,是不能传输的,xml使用最为广泛,而且考虑到跨平台应用,所以这里我们只以xml 数据的传输来示例.在下篇文章,我们将深入解析webservice的精髓---xml 数据传输.今天不早了,早点睡了:)接上篇文章,我们先简单解释下GetSiteAData(string AssignName)函数.函数功能很简单,只是要返回查询结果,其数据格式是XmlDataDocument.当查询失败时(无匹配查询结果),我们构造一个xml,返回一个空记录.否则,我们把查询后的dataset生成一个XmlDataDocument,接下来,由于该项目的需要,我加入了一个循环,添加dataset里所没有的节点,站点名称.在这之后,算是完成了一个符合我们期望格式的xml数据文档,我们把它返回.好了,webservice的方法函数介绍完了(这里还有个web服务方法,稍后介绍),接下来我们的任务是怎么调用它了.首先把webservice的项目编译完成,假定我们这个服务是针对资源站点A的,我们不妨称其为ServiceA.先单独运行asmx文件,执行GetSiteAData(string AssignName)方法,将提示你输入参数,你输入要搜索的内容,点确认,将返回给你一个xml数据,并在ie上显示出来,这就是你搜索到的内容拉.这里对ServiceA的工作再做点介绍,在我们这个项目里,它是资源站点A提供的服务,意思是,它查询的数据将全来源于站点A,而站点A资源添加在本项目也有专门的工程实现.好了,回到正题.这里我介绍vs调用webservice的方法,其实其他平台的调用方法也是大同小异.首先我们介绍web引用方式,这种方式我强烈建议调试时使用,非常方便.右击引用,点添加web引用,输入你的webservice地址,如:http://localhost/aspxproject/WebServiceSolution/SiteBService/service1.asmx,你必须保证你输入的webservice存在.然后引用即可,注意:web引用名将作为你加入的webservice的名字空间.比如你输入了:SiteA,那服务的实例化将是这样:SiteA.Service1 serviceA=newSiteA.Service1();(Service1是服务的类名).完成了这一步,service的调用似乎变的那么简单,我们已经实现了远程实例化,接下来的远程调用也是一样的容易.下面给出资源采集站ServiceGatherSite的绑定代码(只采集A 站点的信息)//绑定数据public void BindData(){serviceA=new SiteA.Service1();DataSet ds=new DataSet();XmlNode xmlNode1;XmlDataDocument xd=new XmlDataDocument();StringBuilder xmlString1;xmlNode1=serviceA.GetSiteAData(strSearch);if(xmlNode1==null) //--存储过程执行失败return;xmlString1=new StringBuilder(xmlNode1.OuterXml);if(xmlString1.ToString().Equals("<NewDataSet xmlns=\"\"></NewDataSet>"))return ;xd.LoadXml(xmlString1.ToString());ds.ReadXml(new XmlNodeReader(xd));DataGrid1.DataSource=ds.Tables["list"].DefaultView;DataGrid1.DataBind();}此段代码给出了xml转化成dataset的解决方案,虽然这不是必须的,但毕竟在 里,dataset占的作用之重,谁都知道的.其他的请朋友们先看(呵呵,个中高手就免了),在下篇文章中将会有对它的一些解释与及多服务分布调用的解决方案,写了三篇了,发现似乎还是有些朋友看的,那我就献丑继续写下去好了,大家有什么意见也希望提出,在下的理解存在偏驳也再所难免,希望谅解:)好了,时候不早了,休息去了,下次有时间继续:)架设webservice简单实例2009-08-24 19:22具体步骤如下:一、打开VS。
webservice接口调用示例WebService接口是一个用于数据交互的网络服务,其接口通常使用HTTP或HTTPS方式调用。
以查询天气信息为例,下面是一个使用WebService接口调用的示例:1. 首先,我们需要获取天气查询接口的地址和参数。
这些信息通常可以在接口提供方的文档中找到。
2. 我们可以使用类似cURL、Python的requests库等工具来发送HTTP请求。
以requests库为例,我们可以在代码中添加如下语句导入requests库:```import requests```3. 接下来,我们需要发送HTTP GET请求获取天气信息。
代码示例如下:```url = '/currentconditions/v1/'payload = {'apikey': 'YOUR_API_KEY', 'location': 'beijing'} response = requests.get(url, params=payload)```4. 上述代码中,我们指定了接口的地址`url`和查询参数`payload`。
此外,我们还需要向接口提供方获取一个API Key,以便进行认证。
5. 接下来,我们可以通过解析服务端响应中的JSON数据获取天气信息。
代码示例如下:```data = response.json()weather_info = data[0]['WeatherText']temperature = data[0]['Temperature']['Metric']['Value']```6. 上述代码中,我们将服务端响应中的JSON数据解析,并获取其中的天气信息和温度信息。
7. 最后,我们可以将结果展示给用户或者进行其他处理。
```result = '北京的天气为{},温度为{}度'.format(weather_info, temperature)print(result)```请注意,上述代码仅为示例,实际的WebService接口调用可能需要进行更多的参数配置和错误处理。
Java调⽤CXFWebService接⼝的两种⽅式实例1.静态调⽤// 创建WebService客户端代理⼯⼚JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();// 判断是否抛出异常factory.getOutInterceptors().add(new LoggingInInterceptor());// 注册webservice接⼝factory.setServiceClass(DeductionService.class);// 配置webservice地址factory.setAddress("http://localhost:7002/card/services/HelloWorld?wsdl");// 获得接⼝对象CxfService service = (CxfService) factory.create();// 调⽤接⼝⽅法String result = service.sayHello("aaaaaaaaaa");System.out.println("调⽤结果:" + result);// 关闭接⼝连接System.exit(0);2.动态调⽤:JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();org.apache.cxf.endpoint.Client client = dcf.createClient("http://localhost:7002/card/services/HelloWorld?wsdl");// url为调⽤webService的wsdl地址QName name = new QName("/", "sayHello");// namespace是命名空间,methodName是⽅法名String xmlStr = "aaaaaaaa";// paramvalue为参数值Object[] objects;try {objects = client.invoke(name, xmlStr);System.out.println(objects[0].toString());} catch (Exception e) {e.printStackTrace();}区别:静态调⽤需要依赖service类,因为客户端调⽤cxf webservice接⼝的过程中需要服务器端提供service,很不⽅便,如果同⼀个项⽬中则没有区别。
WebService1 解决几个问题?2 什么是WebService?3 它能做什么?为什么要学习WebService?学习WebService要达到什么目的?简单的网络应用:先理解什么是服务:现在的应用程序变得越来越复杂,甚至只靠单一的应用程序无法完成全部的工作。
更别说只使用一种语言了。
大家在写应用程序查询数据库时,并没有考虑过为什么可以将查询结果返回给上层的应用程序,甚至认为,这就是数据库应该做的,其实不然,这是数据库通过TCP/IP协议与另一个应用程序进行交流的结果,而上层是什么样的应用程序,是用什么语言,数据库本身并不知道,它只知道接收到了一份协议,这就是SQL92查询标准协议。
目前的云计算、云查杀都是一种服务,现在比较流行的说法是SOA(面向服务的框架)。
既然数据库可以依据某些标准对外部其他应用程序提供服务、而且不关心对方使用什么语言,那我们为什么就不能实现跨平台、跨语言的服务呢?只要我们用Java写的代码,可以被任意的语言所调用,我们就实现了跨平台,跨语言的服务!---WebService复杂的网络应用:对几个问题的回答:1.WebService,顾名思义就是基于Web的服务。
它使用Web(HTTP)方式,接收和响应外部系统的某种请求。
从而实现远程调用.2.我们可以调用互联网上查询天气信息Web服务,然后将它嵌入到我们的程序(C/S或B/S程序)当中来,当用户从我们的网点看到天气信息时,他会认为我们为他提供了很多的信息服务,但其实我们什么也没有做,只是简单调用了一下服务器上的一段代码而已。
3.学习WebService可以将你的服务(一段代码)发布到互联网上让别人去调用,也可以调用别人机器上发布的WebService,就像使用自己的代码一样.。
在开始之前必须要让先了解几个名词:名词1:XML. Extensible Markup Language -扩展性标记语言XML,用于传输格式化的数据,是Web服务的基础。
excel中webservice用法在Excel中,可以使用Web服务来获取或更新来自Web服务器的数据。
通过使用Web服务功能,可以通过简单的函数调用来获取数据,而无需编写复杂的代码。
要在Excel中使用Web服务,首先需要确定要访问的Web服务的URL。
然后,可以使用"WEBSERVICE"函数来获取此URL返回的数据。
下面是使用WebService的步骤:1. 打开Excel并在单元格中输入要访问的Web服务的URL。
例如,假设我们想要获取一个返回当天天气预报的Web服务的数据,我们可以将该URL输入到单元格A1中。
2. 在要获取数据的单元格中,使用"WEBSERVICE"函数来调用Web服务。
函数的语法为:`=WEBSERVICE(url)`。
在我们的例子中,我们可以在B1单元格中输入`=WEBSERVICE(A1)`。
3. 按下Enter键后,Excel将通过发送HTTP请求到指定的URL,并将返回的数据显示在B1单元格中。
4. 如果需要将返回的数据解析为特定的格式,可以使用Excel的其他函数来进一步处理。
例如,可以使用"FILTERXML"函数来解析XML数据,或使用"JSON"函数来处理JSON数据。
需要注意的是,如果Web服务返回的数据需要身份验证或其他参数,可以在URL中包含这些参数。
也可以在URL后面添加查询字符串,将参数传递给Web服务。
使用Excel中的Web服务功能,可以轻松地从Web服务器获取所需的数据,并将其与其他Excel函数和功能结合使用。
这使得在Excel中进行数据分析和报告生成变得更加便捷和高效。
希望以上内容对您有所帮助!如果还有任何问题,请随时提问。
WebService案例Springboot+CXF开发WebServiceDemo ⼀、本次开发除了⽤到spring boot基础jar包外,还⽤到了cxf相关jar包:1 <!-- cxf⽀持 -->2 <dependency>3 <groupId>org.apache.cxf</groupId>4 <artifactId>cxf-rt-frontend-jaxws</artifactId>5 <version>3.1.6</version>6 </dependency>7 <dependency>8 <groupId>org.apache.cxf</groupId>9 <artifactId>cxf-rt-transports-http</artifactId>10 <version>3.1.6</version>11 </dependency>⼆、⾸先我们创建⼀个实体类,内容是关于⽤户信息的查询和记录:1 import java.io.Serializable;2 import java.util.Date;34 public class User implements Serializable {56 private static final long serialVersionUID = -5939599230753662529L;7 private String userId;8 private String username;9 private String age;10 private Date updateTime;11 //getter setter ......12 public void setUserId(String userId) {13 erId=userId;14 }15 public void setUsername(String username) {16 ername=username;17 }18 public void setAge(String age) {19 this.age=age;20 }21 public void setUpdateTime(Date updateTime) {22 this.updateTime=updateTime;23 }242526 public String getUserId() {27 return userId;28 }29 public String getUserName() {30 return username;31 }32 public String getAge() {33 return age;34 }35 public Date getUpdateTime() {36 return updateTime;37 }38 }三、接下来我们创建接⼝类:1 import javax.jws.WebMethod;2 import javax.jws.WebParam;3 import javax.jws.WebService;45 import er;678 @WebService9 public interface UserService {1011 @WebMethod12 String getName(@WebParam(name = "userId") String userId);13 @WebMethod14 User getUser(String userId);15 }四、有了接⼝类,那么接下来我们对接⼝进⾏实现,也就是接⼝实现类(也就是业务类)代码:1 package cn.paybay.demo.service.impl;23 import java.util.Date;4 import java.util.HashMap;5 import java.util.Map;6789 import javax.jws.WebService;1011 import er;12 import erService;1314 @WebService(targetNamespace="/",endpointInterface = "erService")15 public class UserServiceImpl implements UserService{1617 private Map<String, User> userMap = new HashMap<String, User>();18 public UserServiceImpl() {19 System.out.println("向实体类插⼊数据");20 User user = new User();21 user.setUserId("411001");22 user.setUsername("zhansan");23 user.setAge("20");24 user.setUpdateTime(new Date());25 userMap.put(user.getUserId(), user);2627 user = new User();28 user.setUserId("411002");29 user.setUsername("lisi");30 user.setAge("30");31 user.setUpdateTime(new Date());32 userMap.put(user.getUserId(), user);3334 user = new User();35 user.setUserId("411003");36 user.setUsername("wangwu");37 user.setAge("40");38 user.setUpdateTime(new Date());39 userMap.put(user.getUserId(), user);40 }41 @Override42 public String getName(String userId) {43 return "liyd-" + userId;44 }45 @Override46 public User getUser(String userId) {47 System.out.println("userMap是:"+userMap);48 return userMap.get(userId);49 }5051 }注释(PS):在发布服务之前,我们要在这⾥对业务实现类进⾏⼀下说明,请⼤家看下图箭头指向的⽅框部分(图⼀)下⾯我来解释⼀下加上图⽅框箭头所指代码的⽬的:/:这是我的业务类所在路径;/:这是我的接⼝类所在路径;在不加上图⽅框箭头所指代码的情况下,你最后发服务的结果是这样的(如下图):(图⼆)并且会在你进⾏客户端调⽤的时候回报错:No operation was found with the name {/}getUser.那么原因就是:在CXF发布服务的时候,发布的是业务类(UserServiceImpl.java),那么默认的命名空间就会是业务类所在包(路径),⽽对外界暴露的则是接⼝类(UserService.java),那么对于客户端调⽤的时侯,需要按照接⼝类所在路径进⾏命名空所以在发布之前我们要在业务类(UserServiceImpl.java)上增加注解,指定命名空间,然后再进⾏发布,那么我们最终在加上(图⼀)⽅框箭头所指代码情况下,发布服务的结果为下图(请看图三):(图三)五、(发布服务)接⼝类,业务类代码都已经准备好,那么我接下来我就要对webservice服务进⾏发布:代码如下:1 23 import javax.xml.ws.Endpoint;45 import org.apache.cxf.Bus;6 import org.apache.cxf.bus.spring.SpringBus;7 import org.apache.cxf.jaxws.EndpointImpl;8 import org.apache.cxf.transport.servlet.CXFServlet;9 import org.springframework.boot.web.servlet.ServletRegistrationBean;10 import org.springframework.context.annotation.Bean;11 import org.springframework.context.annotation.Configuration;1213 import erService;14 import erServiceImpl;151617 @Configuration18 public class TestConfig {1920 @Bean21 public ServletRegistrationBean dispatcherServlet() {22 return new ServletRegistrationBean(new CXFServlet(), "/test/*");23 }24 @Bean(name = Bus.DEFAULT_BUS_ID)25 public SpringBus springBus() {26 return new SpringBus();27 }28 @Bean29 public UserService userService() {30 return new UserServiceImpl();31 }32 @Bean33 public Endpoint endpoint() {34 EndpointImpl endpoint = new EndpointImpl(springBus(), userService());35 endpoint.publish("/user");36 return endpoint;37 }3839 }那么到这⾥呢,我们的所有的步骤基本完成了,启动spring boot 然后再浏览器中输⼊url:http://localhost:8080/webservice/test/user?wsdl可以看到有相关的wsdl描述信息输出了,说明服务已经发布了。
cxf WebService设置wsdl中soapAction的值用cxf开发一个WebService很简单,只需要下面几步:1.定义接口public interface HelloService {String hello();}2.实现public class HelloServiceImpl implements HelloService {@Overridepublic String hello() {return "hi,my name is gyoung ";}}3.用ServerFactoryBean生成服务复制代码public static void main(String[] args) {HelloServiceImpl helloworldImpl = new HelloServiceImpl();//cxf发布服务的工厂beanServerFactoryBean svrFactory = new ServerFactoryBean();//设置服务类svrFactory.setServiceClass(HelloService.class);//设置服务地址svrFactory.setAddress("http://localhost:9001/Hello");//设置服务beansvrFactory.setServiceBean(helloworldImpl);svrFactory.create();}复制代码这样,一个简单的HelloWorld服务便生成成功了。
但是,这样生成的服务有一个问题,wsdl中的soapAction属性是空的复制代码<wsdl:binding name="HelloServiceSoapBinding" type="tns:HelloServicePortType"><soap:binding style="document" transport="/soap/http"/> <wsdl:operation name="hello"><soap:operation soapAction="" style="document"/><wsdl:input name="hello"><soap:body use="literal"/></wsdl:input><wsdl:output name="helloResponse"><soap:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding>复制代码这一段<soap:operation soapAction="" style="document"/>,如果是.net生成的服务,soapAction是有值的复制代码<wsdl:binding name="WebService1Soap" type="tns:WebService1Soap"><soap:binding transport="/soap/http"/><wsdl:operation name="HelloWorld"><soap:operation soapAction="/HelloWorld" style="document"/><wsdl:input><soap:body use="literal"/></wsdl:input><wsdl:output><soap:body use="literal"/></wsdl:output></wsdl:operation></wsdl:binding>复制代码查看了很久的源码,才发现,设置cxf设置soapAction是在org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean类中它会去循环遍历serviceConfigurations,调用其getAction方法来获取action的值。
最近开发开始学习Web Service,如果你是大神,请路过!谢谢!遵循前辈大神们的教导~~~,内事不决问度娘,外事不决问谷歌(现在谷歌已经不能用了),只能问度娘了!上网一百度,套用周董的一句歌词,霍,霍,霍,霍,这么多的套路(axis,axis2,XFire,CXF等),我到底选择哪一个?因为要和Spring进行对接,看了一下,CXF与Spring的耦合度最好,于是就选择了CXF。
上官网下jar包,下了最新的apache-cxf-3.1.4.zip包。
解压出来,看看里面的最简单的实例,apache-cxf-3.1.4\samples\java_first_jaxws,本着你快乐所以我快乐加上不要脸的原则,我抄抄抄,改了一下名字,开发环境jdk1.6, jdk1.5没试过,上眼呐!新建工程mywbs,导入jar包cxf-core-3.1.4.jarjetty-continuation-9.2.11.v20150529.jarjetty-http-9.2.11.v20150529.jarjetty-io-9.2.11.v20150529.jarjetty-server-9.2.11.v20150529.jarjetty-util-9.2.11.v20150529.jarwsdl4j-1.6.3.jarxmlschema-core-2.2.1.jar一、接口类IHelloWorld.javapackage com.ws.hello;import java.util.List;import javax.jws.WebService;import ers;@WebServicepublic interface IHelloWorld {public String sayHello(String name);public String getUserName(Users user);public List<Users> getListUser();}二、实现类(说明endpointInterface = "com.ws.hello.IHelloWorld",IHelloWorld 类加上路径,此处注意)HelloWorldImpl.javapackage com.ws.hello;import java.util.ArrayList;import java.util.List;import javax.jws.WebService;import ers;@WebService(endpointInterface = "com.ws.hello.IHelloWorld",serviceName = "IHelloWorld", portName="IHelloWorldPort")public class HelloWorldImpl implements IHelloWorld {@Overridepublic String sayHello(String name) {return name + ": 您好啊!";}@Overridepublic String getUserName(Users user) {return user.getName();}@Overridepublic List<Users> getListUser() {System.out.println("getListUser called~~~");List<Users> list = new ArrayList<Users>();list.add(new Users(2,"张三"));list.add(new Users(3, "十八罗汉"));list.add(new Users(4,"五王"));return list;}}三、实体类Userspackage com.ws.entity;import java.io.Serializable;public class Users implements Serializable{private static final long serialVersionUID= -5031894017095689998L;private Integer id;private String name;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}public Users(Integer id, String name) {super();this.id = id; = name;}public Users() {super();}}Users类如果不写默认构造方法,将报如下异常:Exception in thread "main" javax.xml.ws.WebServiceException: Unable to create JAXBContextatcom.sun.xml.internal.ws.model.AbstractSEIModelImpl.createJAXBContext( Unknown Source)atcom.sun.xml.internal.ws.model.AbstractSEIModelImpl.postProcess(Unknow n Source)atcom.sun.xml.internal.ws.model.RuntimeModeler.buildRuntimeModel(Unknow n Source)atcom.sun.xml.internal.ws.server.EndpointFactory.createSEIModel(Unknown Source)atcom.sun.xml.internal.ws.server.EndpointFactory.createEndpoint(Unknown Source)at com.sun.xml.internal.ws.api.server.WSEndpoint.create(Unknown Source)at com.sun.xml.internal.ws.api.server.WSEndpoint.create(Unknown Source)atcom.sun.xml.internal.ws.transport.http.server.EndpointImpl.createEndp oint(Unknown Source)atcom.sun.xml.internal.ws.transport.http.server.EndpointImpl.publish(Un known Source)atcom.sun.xml.internal.ws.spi.ProviderImpl.createAndPublishEndpoint(Unk nown Source)at javax.xml.ws.Endpoint.publish(Endpoint.java:220)atcom.ws.deploy.DeployHelloWorldService.<init>(DeployHelloWorldService. java:14)atcom.ws.deploy.DeployHelloWorldService.main(DeployHelloWorldService.ja va:23)Caused by: java.security.PrivilegedActionException:com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptionsers does not have a no-arg default constructor.this problem is related to the following location:at ersat public java.util.Listcom.ws.hello.jaxws.GetListUserResponse._returnat com.ws.hello.jaxws.GetListUserResponseat java.security.AccessController.doPrivileged(Native Method)... 13 moreCaused by:com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptionsers does not have a no-arg default constructor.this problem is related to the following location:at ersat public java.util.Listcom.ws.hello.jaxws.GetListUserResponse._returnat com.ws.hello.jaxws.GetListUserResponseatcom.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException$Buil der.check(Unknown Source)atcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(U nknown Source)atcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl.<init>(Unknown Source)atcom.sun.xml.internal.bind.v2.runtime.JAXBContextImpl$JAXBContextBuild er.build(Unknown Source)atcom.sun.xml.internal.bind.v2.ContextFactory.createContext(Unknown Source)at com.sun.xml.internal.bind.api.JAXBRIContext.newInstance(Unknown Source)atcom.sun.xml.internal.ws.developer.JAXBContextFactory$1.createJAXBCont ext(Unknown Source)atcom.sun.xml.internal.ws.model.AbstractSEIModelImpl$1.run(UnknownSource)atcom.sun.xml.internal.ws.model.AbstractSEIModelImpl$1.run(Unknown Source)... 14 more晕了,真是崩溃了,就写了这么几句话!错误代码比正常代码还要多!真是婶婶能忍叔叔不能忍,虽然英语很烂,连猜带蒙吧,看黑色的一句话,大概似乎是告诉我们Users类中没有默认的构造方法,果断加上,错误消失!此处应有掌声!鼓掌!!!四、DeployHelloWorldService.javapackage com.ws.deploy;import javax.xml.ws.Endpoint;import com.ws.hello.HelloWorldImpl;public class DeployHelloWorldService {protected DeployHelloWorldService() throws Exception {System.out.println("Starting Server");HelloWorldImpl implementor = new HelloWorldImpl();//工程名String address = "http://localhost:8080/mywbs";Endpoint.publish(address, implementor);}/*** @param args* @throws Exception*/public static void main(String[] args) throws Exception { new DeployHelloWorldService();System.out.println("Server ready...");Thread.sleep(5 * 60 * 1000);System.out.println("Server exiting");System.exit(0);}}点击运行,正常的话会有Starting ServerServer ready...在IE地址栏中输入:http://localhost:8080/mywbs?wsdl什么你不知道IE地址栏在哪里,对不起,大哥,地球是危险的,你回火星去吧!如果正常的话呢,大约在网页上会出现下面的信息,只截取一部分,注意画粗红线的地方,下面我们用的到。