基于CXF实现JAVA_WebService
- 格式:doc
- 大小:60.00 KB
- 文档页数:6
WebService开发笔记 1 -- 利用cxf开发WebService竟然如此简单关键字: webservice cxf soaWebService开发笔记 1 -- 利用cxf开发WebService竟然如此简单现在的项目中需要用到SOA概念的地方越来越多,最近我接手的一个项目中就提出了这样的业务要求,需要在.net开发的客户端系统中访问java开发的web 系统,这样的业务需求自然需要通过WebService进行信息数据的操作。
下面就将我们在开发中摸索的一点经验教训总结以下,以供大家参考.在WebService开发笔记 2 -- VS 2005 访问WebServcie更简单中作一个跨平台访问WebServcie服务的例子....在WebService开发笔记 3 -- 增强访问 WebService 的安全性通过一个简单的用户口令验证机制来加强一下WebService的安全性....我们项目的整个架构使用的比较流行的WSH MVC组合,即webwork2 + Spring + Hibernate;1.首先集成Apacha CXF WebService 到 Spring 框架中;apache cxf 下载地址:/dist/incubator/cxf/2.0.4-incubator/apache -cxf-2.0.4-incubator.zip在spring context配置文件中引入以下cxf配置Xml代码1.<import resource="classpath*:META-INF/cxf/cxf.xml"/>2.<import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml"/>3.<import resource="classpath*:META-INF/cxf/cxf-servlet.xml"/>在web.xml中添加过滤器:Xml代码1.<servlet>2.<servlet-name>CXFServlet</servlet-name>3.<servlet-class>4. org.apache.cxf.transport.servlet.CXFServlet5.</servlet-class>6.</servlet>7.<servlet-mapping>8.<servlet-name>CXFServlet</servlet-name>9.<url-pattern>/services/*</url-pattern>10.</servlet-mapping>2.开发服务端WebService接口:Java代码1./**2. * WebService接口定义类.3. *4. * 使用@WebService将接口中的所有方法输出为Web Service.5. * 可用annotation对设置方法、参数和返回值在WSDL中的定义.6. */7.@WebService8.public interface WebServiceSample {9.10.11. /**12. * 一个简单的方法,返回一个字符串13. * @param hello14. * @return15. */16. String say(String hello);17.18. /**19. * 稍微复杂一些的方法,传递一个对象给服务端处理20. * @param user21. * @return22. */23. String sayUserName(24. @WebParam(name = "user")25. UserDTO user);26.27. /**28. * 最复杂的方法,返回一个List封装的对象集合29. * @return30. */31. public32. @WebResult(partName="o")33. ListObject findUsers();34.35.}由简单到复杂定义了三个接口,模拟业务需求;3.实现接口Java代码1./**2. * WebService实现类.3. *4. * 使用@WebService指向Interface定义类即可.5. */6.@WebService(endpointInterface = ".examples.webservice.WebServiceSample")7.public class WebServiceSampleImpl implements WebServiceSample {8.9. public String sayUserName(UserDTO user) {10. return "hello "+user.getName();11. }12.13. public String say(String hello) {14. return "hello "+hello;15. }16.17. public ListObject findUsers() {18. ArrayList<Object> list = new ArrayList<Object>();19.20. list.add(instancUser(1,"lib"));21. list.add(instancUser(2,"mld"));22. list.add(instancUser(3,"lq"));23. list.add(instancUser(4,"gj"));24. ListObject o = new ListObject();25. o.setList(list);26. return o;27. }28.29. private UserDTO instancUser(Integer id,String name){30. UserDTO user = new UserDTO();31. user.setId(id);32. user.setName(name);33. return user;34. }35.}4.依赖的两个类:用户对象与List对象Java代码1./**2. * Web Service传输User信息的DTO.3. *4. * 分离entity类与web service接口间的耦合,隔绝entity类的修改对接口的影响.5. * 使用JAXB 2.0的annotation标注JAVA-XML映射,尽量使用默认约定.6. *7. */8.@XmlAccessorType(XmlAccessType.FIELD)9.@XmlType(name = "User")10.public class UserDTO {11.12. protected Integer id;13.14. protected String name;15.16. public Integer getId() {17. return id;18. }19.20. public void setId(Integer value) {21. id = value;22. }23.24. public String getName() {25. return name;26. }27.28. public void setName(String value) {29. name = value;30. }31.}关于List对象,参照了有关JWS的一个问题中的描述:DK6.0 自带的WebService 中 WebMethod的参数好像不能是ArrayList 或者其他List传递List需要将List 包装在其他对象内部才行 (个人理解如有不对请指出) ,我在实践中也遇到了此类问题.通过以下封装的对象即可以传递List对象.Java代码1./**2. * <p>Java class for listObject complex type.3. *4. * <p>The following schema fragment specifies the expected content contained within this class.5. *6. * <pre>7. * <complexType name="listObject">8. * <complexContent>9. * <restriction base="{/2001/XMLSchema}anyType">10. * <sequence>11. * <element name="list" type="{/2001/XMLSchema}anyType" maxOccurs="unbounded" minOccurs="0"/>12. * </sequence>13. * </restriction>14. * </complexContent>15. * </complexType>16. * </pre>17. *18. *19. */20.@XmlAccessorType(XmlAccessType.FIELD)21.@XmlType(name = "listObject", propOrder = { "list" })22.public class ListObject {23.24. @XmlElement(nillable = true)25. protected List<Object> list;26.27. /**28. * Gets the value of the list property.29. *30. * <p>31. * This accessor method returns a reference to the live list,32. * not a snapshot. Therefore any modification you make to the33. * returned list will be present inside the JAXB object.34. * This is why there is not a <CODE>set</CODE> method for the list property.35. *36. * <p>37. * For example, to add a new item, do as follows:38. * <pre>39. * getList().add(newItem);40. * </pre>41. *42. *43. * <p>44. * Objects of the following type(s) are allowed in the list45. * {@link Object }46. *47. *48. */49. public List<Object> getList() {50. if (list == null) {51. list = new ArrayList<Object>();52. }53. return this.list;54. }55.56. public void setList(ArrayList<Object> list) {57. this.list = list;58. }59.60.}5.WebService 服务端 spring 配置文件 ws-context.xmlXml代码1.<beans xmlns="/schema/beans"2.xmlns:xsi="http://www.w/2001/XMLSchema-instance"3.xmlns:jaxws="/jaxws"4.xsi:schemaLocation="/jaxws http://cxf./schemas/jaxws.xsd /sch ema/beans /schema/beans/spring-b eans.xsd"5.default-autowire="byName"default-lazy-init="true">6.7.<jaxws:endpoint id="webServiceSample"8.address="/WebServiceSample"implementor=".coral.biz.examples.webservice.WebServiceSampleImpl"/>9.10.</beans>WebService 客户端 spring 配置文件 wsclient-context.xmlXml代码1.<beans xmlns="/schema/beans"2.xmlns:xsi="http://www.w/2001/XMLSchema-instance"3.xmlns:jaxws="/jaxws"4.xsi:schemaLocation="/jaxws http://cxf./schemas/jaxws.xsd /sch ema/beans /schema/beans/spring-b eans.xsd"5.default-autowire="byName"default-lazy-init="true">6.7. <!-- ws client -->8.<bean id="identityValidateServiceClient"class=".coral.admin.service.IdentityValidateService"9.factory-bean="identityValidateServiceClientFactory"factory-method="create"/>10.11. <bean id="identityValidateServiceClientFactory"12. class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">13. <property name="serviceClass"14. value=".coral.admin.service.IdentityValidateService"/>15. <property name="address"16. value="http://88.148.29.54:8080/coral/services/IdentityValidateService"/>17. </bean>18.19.</beans>6.发布到tomcat服务器以后通过以下地址即可查看自定义的webservice接口生成的wsdl:http://88.148.29.54:8080/aio/services/WebServiceSample?wsdl7.调用WebService接口的Junit单元测试程序Java代码1.package test.coral.sample;2.3.import org.springframework.test.AbstractDependencyInjectionSpringContextTests;4.5.import .examples.webservice.WebServiceSample;6.import erDTO;7.8.public class TestWebServiceSample extends9. AbstractDependencyInjectionSpringContextTests {10. WebServiceSample webServiceSampleClient;11.12. public void setWebServiceSampleClient(WebServiceSample webServiceSampleClient) {13. this.webServiceSampleClient = webServiceSampleClient;14. }15.16. @Override17. protected String[] getConfigLocations() {18. setAutowireMode(AUTOWIRE_BY_NAME);19. //spring 客户端配置文件保存位置20. return new String[] { "classpath:/cn/org/coral/biz/examples/webservice/wsclient-context.xml" };21. }22.23. public void testWSClinet(){24. Assert.hasText(webServiceSampleClient.say(" world"));25. }26.}。
CXF入门教程(5)--webService异步调用模式除了常见的同步调用模式,CXF还支持如下两种形式的异步调用模式:•轮询方法(Polling approach) - 这种情况下调用远程方法,我们可以调用一个特殊的方法;该方法没有输出参数,但是返回一个 javax.xml.ws.Response 实例。
可以轮询该 Response 对象(继承自 javax.util.concurrency.Future 接口)来检查是否有应答消息到达。
•回调方法(Callback approach) -这种情况下调用远程方法,我们调用另外一个特殊的方法:该方法使用一个回调对象(javax.xml.ws.AsyncHandler类型)的引用作为一个参数。
只要有应答消息到达客户端,CXF运行时就会回调该 AsyncHandler 对象,并将应答消息的内容传给它。
下面是两种异步调用的方法的描述和示例代码。
异步调用示例使用的契约下面展示的是异步调用示例中使用的WSDL契约,为保证教程的连续性,本文使用的是前面教程(1)中生成的HelloWorld服务的WSDL契约。
[html] view plaincopyprint?1.<?xml version="1.0" ?>2.<wsdl:definitions name="HelloWorld"3.targetNamespace="/"4.xmlns:ns1="/soap/http" xmlns:soap="/wsdl/soap/"5.xmlns:tns="/" xmlns:wsdl="/wsdl/"6.xmlns:xsd="/2001/XMLSchema">7.<wsdl:types>8.<xs:schema attributeFormDefault="unqualified"9.elementFormDefault="unqualified" targetNamespace="/ "10.xmlns:tns="/" xmlns:xs="/2001/XMLSchema">11.<xs:element name="IntegerUserMap" type="tns:Integ erUserMap"></xs:element>12.<xs:complexType name="User">13.<xs:sequence>14.<xs:element minOccurs="0" name="name" type="xs:s tring"></xs:element>15.</xs:sequence>16.</xs:complexType>17.<xs:complexType name="IntegerUserMap">18.<xs:sequence>19.<xs:element maxOccurs="unbounded" minOccurs="0 " name="entry"20.type="tns:IdentifiedUser"></xs:element>21.</xs:sequence>22.</xs:complexType>23.<xs:complexType name="IdentifiedUser">24.<xs:sequence>25.<xs:element name="id" type="xs:int"></xs:element>26.<xs:element minOccurs="0" name="user" type="tns:U ser"></xs:element>27.</xs:sequence>28.</xs:complexType>29.<xs:element name="sayHi" type="tns:sayHi"></xs:ele ment>30.<xs:complexType name="sayHi">31.<xs:sequence>32.<xs:element minOccurs="0" name="text" type="xs:str ing"></xs:element>33.</xs:sequence>34.</xs:complexType>35.<xs:element name="sayHiResponse" type="tns:sayHiR esponse"></xs:element>36.<xs:complexType name="sayHiResponse">37.<xs:sequence>38.<xs:element minOccurs="0" name="return" type="xs: string"></xs:element>39.</xs:sequence>40.</xs:complexType>41.<xs:element name="sayHiToUser" type="tns:sayHiToU ser"></xs:element>42.<xs:complexType name="sayHiToUser">43.<xs:sequence>44.<xs:element minOccurs="0" name="arg0" type="tns: User"></xs:element>45.</xs:sequence>46.</xs:complexType>47.<xs:element name="sayHiToUserResponse" type="tns: sayHiToUserResponse"></xs:element>48.<xs:complexType name="sayHiToUserResponse">49.<xs:sequence>50.<xs:element minOccurs="0" name="return" type="xs: string"></xs:element>51.</xs:sequence>52.</xs:complexType>53.<xs:element name="getUsers" type="tns:getUsers">< /xs:element>54.<xs:complexType name="getUsers">55.<xs:sequence></xs:sequence>56.</xs:complexType>57.<xs:element name="getUsersResponse" type="tns:get UsersResponse"></xs:element>58.<xs:complexType name="getUsersResponse">59.<xs:sequence>60.<xs:element minOccurs="0" name="return" type="tns :IntegerUserMap"></xs:element>61.</xs:sequence>62.</xs:complexType>63.</xs:schema>64.</wsdl:types>65.<wsdl:message name="getUsers">66.<wsdl:part element="tns:getUsers" name="parameter s">67.</wsdl:part>68.</wsdl:message>69.<wsdl:message name="sayHi">70.<wsdl:part element="tns:sayHi" name="parameters">71.</wsdl:part>72.</wsdl:message>73.<wsdl:message name="sayHiT oUser">74.<wsdl:part element="tns:sayHiT oUser" name="param eters">75.</wsdl:part>76.</wsdl:message>77.<wsdl:message name="sayHiT oUserResponse">78.<wsdl:part element="tns:sayHiT oUserResponse" name ="parameters">79.</wsdl:part>80.</wsdl:message>81.<wsdl:message name="sayHiResponse">82.<wsdl:part element="tns:sayHiResponse" name="para meters">83.</wsdl:part>84.</wsdl:message>85.<wsdl:message name="getUsersResponse">86.<wsdl:part element="tns:getUsersResponse" name=" parameters">87.</wsdl:part>88.</wsdl:message>89.<wsdl:portType name="iHelloWorld">90.<wsdl:operation name="sayHi">91.<wsdl:input message="tns:sayHi" name="sayHi">92.</wsdl:input>93.<wsdl:output message="tns:sayHiResponse" name="s ayHiResponse">94.</wsdl:output>95.</wsdl:operation>96.<wsdl:operation name="sayHiT oUser">97.<wsdl:input message="tns:sayHiToUser" name="sayHi ToUser">98.</wsdl:input>99.<wsdl:output message="tns:sayHiT oUserResponse" na me="sayHiT oUserResponse">100.</wsdl:output>101.</wsdl:operation>102.<wsdl:operation name="getUsers">103.<wsdl:input message="tns:getUsers" name="getUsers ">104.</wsdl:input>105.<wsdl:output message="tns:getUsersResponse" name ="getUsersResponse">106.</wsdl:output>107.</wsdl:operation>108.</wsdl:portType>109.<wsdl:binding name="HelloWorldSoapBinding" type= "tns:iHelloWorld">110.<soap:binding style="document"111.transport="/soap/http"></soap:binding>112.<wsdl:operation name="sayHi">113.<soap:operation soapAction="" style="document">< /soap:operation>114.<wsdl:input name="sayHi">115.<soap:body use="literal"></soap:body>116.</wsdl:input>117.<wsdl:output name="sayHiResponse">118.<soap:body use="literal"></soap:body>119.</wsdl:output>120.</wsdl:operation>121.<wsdl:operation name="sayHiT oUser">122.<soap:operation soapAction="" style="document">< /soap:operation>123.<wsdl:input name="sayHiToUser">124.<soap:body use="literal"></soap:body>125.</wsdl:input>126.<wsdl:output name="sayHiToUserResponse">127.<soap:body use="literal"></soap:body>128.</wsdl:output>129.</wsdl:operation>130.<wsdl:operation name="getUsers">131.<soap:operation soapAction="" style="document">< /soap:operation>132.<wsdl:input name="getUsers">133.<soap:body use="literal"></soap:body>134.</wsdl:input>135.<wsdl:output name="getUsersResponse">136.<soap:body use="literal"></soap:body>137.</wsdl:output>138.</wsdl:operation>139.</wsdl:binding>140.<wsdl:service name="HelloWorld">141.<wsdl:port binding="tns:HelloWorldSoapBinding" na me="HelloWorldImplPort">142.<soap:address location="http://localhost:9000/helloW orld"></soap:address>143.</wsdl:port>144.</wsdl:service>145.</wsdl:definitions>生成异步 stub 代码异步调用需要额外的stub代码(例如,服务端点接口中定义的专用的异步方法)。
⽤cxf⽣成webservice的java客户端代码
百度来的:
最近,由于要⽤到某公司提供的webservice实现的api接⼝,想到了⽤cxf的wsdl2java⼯具来⽣成客户端程序。
(⾃⼰写是⽐较⿇烦且费时,so偷懒⼀下、、)
使⽤步骤如下:
⼀、下载apache cxf的包,如apache-cxf-2.7.10.zip,地址:/download.html
⼆、解压apache-cxf-2.7.10.zip⾄某⼀⽬录,如D:\apache-cxf-2.7.10
三、设置环境变量
1、CXF_HOME=D:\apache-cxf-2.7.10
2、在path后⾯加上 %CXF_HOME%/bin;
在cmd命令中输⼊wsdl2java,如果有提⽰usage,就表明配置成功
四、运⾏wsdl2java⼯具
附wsdl2java⽤法:
wsdl2java -p com -d D:\\src -all xx.wsdl
-p 指定其wsdl的命名空间,也就是要⽣成代码的包名:
-d 指定要产⽣代码所在⽬录
-client ⽣成客户端测试web service的代码
-server ⽣成服务器启动web service的代码
-impl ⽣成web service的实现代码
-ant ⽣成build.xml⽂件
-all ⽣成所有开始端点代码:types,service proxy,,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.。
ESB基于 CXF 实现 Web Service 开发项目:企业服务总线 ESB 编写:华腾 ESB 项目组ESB文档版本 版本号 修改日期 1.0 2009-10-14 1.1 2010-01-12编写 林荣坤 田坤评审批准修改内容 初稿 修正ESB目录基于 CXF 实现 Web Service 开发..................................................................................................... 1 1 简介........................................................................................................................................... 4 1.1 CXF 功能特性 .......................................................................................................... 4 1.2 CXF 项目目标 .......................................................................................................... 4 2 开发环境需求及工具安装 ....................................................................................................... 6 2.1 CXF 安装包 ............................................................................................................. 6 2.1.1 下载及目录结构 ............................................................................................... 6 2.1.2 CXF 框架支撑环境 ........................................................................................... 9 2.1.3 JDK 版本选择、下载和安装 ......................................................................... 10 2.1.4 Servlet 容器下载和安装................................................................................ 10 3 CXF 环境配置及示例运行...................................................................................................... 10 4 SOAP OVER JMS 开发 ............................................................................................................ 12 4.1 文本 JNDI 配置 ...................................................................................................... 12 4.2 服务契约优先 ......................................................................................................... 12 4.3 命令行方式生成服务端 ......................................................................................... 12 4.4 命令行方式生成客户端 ......................................................................................... 14 4.5 测试......................................................................................................................... 15 5 集成 Sping ............................................................................................................................... 15 5.1 服务契约修改 ......................................................................................................... 15 5.2 代码生成................................................................................................................. 16 5.3 Spring 配置 ............................................................................................................. 16 5.3.1 服务端配置 ..................................................................................................... 16 5.3.2 客户端配置 ..................................................................................................... 18 5.4 其他设置................................................................................................................. 20 5.4.1 配置拦截器 ..................................................................................................... 20 5.4.2 配置特征 ......................................................................................................... 21 5.4.3 配置编码 ......................................................................................................... 21 5.5 Sping 加载方式 ...................................................................................................... 21 5.5.1 独立加载 ......................................................................................................... 21 5.5.2 容器加载 ......................................................................................................... 21 5.6 测试......................................................................................................................... 22 6 集成 WebSphere Application Server v6.1 ........................................................................... 23 6.1 删除 Servlet 和 HTTP 服务器相关包.................................................................... 23 6.2 修改 WEB 模块类加载方式 .................................................................................. 23ESB1 简介本文档介绍定义好服务 WSDL、schema 文件后,通过 WSDL First 的方式,基于 CXF 的 JAX-WS 实现 Web Service 开发。
Java WebService 接口实现方式什么是 WebServiceWebService 是一种基于 Web 的服务通信协议,通过使用标准的 HTTP 协议传输数据,使得不同平台、不同语言的应用程序能够进行互操作。
它使用 XML 格式来描述请求和响应的数据,并使用 SOAP(简单对象访问协议)来封装和传输这些数据。
WebService 可以提供各种功能,例如数据查询、数据传输、远程过程调用等。
它是一种跨平台、跨语言的解决方案,能够实现不同系统之间的集成和通信。
Java WebService 实现方式Java 提供了多种方式来实现 WebService 接口,下面介绍两种常用的实现方式。
JAX-WSJAX-WS(Java API for XML Web Services)是 Java EE 的一部分,用于开发和部署 WebService。
它提供了一种简单的方式来创建和发布 WebService 接口。
创建接口首先,我们需要定义一个接口,用于描述我们要提供的服务。
接口中的每个方法都将成为可远程调用的操作。
import javax.jws.WebMethod;import javax.jws.WebService;@WebServicepublic interface MyWebService {@WebMethodString sayHello(String name);}在上面的例子中,我们定义了一个名为MyWebService的接口,其中有一个名为sayHello的方法,该方法接受一个字符串参数并返回一个字符串结果。
实现接口接下来,我们需要实现上述接口。
这里我们可以使用一个普通的 Java 类来实现接口中的方法。
@WebService(endpointInterface = "com.example.MyWebService")public class MyWebServiceImpl implements MyWebService {@Overridepublic String sayHello(String name) {return "Hello, " + name + "!";}}在上面的例子中,我们创建了一个名为MyWebServiceImpl的类,并实现了MyWebService接口中的sayHello方法。
javawebservice-cxf使⽤总结⼀1.创建maven项⽬加⼊pom依赖<dependency><groupId>org.apache.cxf</groupId><artifactId>apache-cxf</artifactId><version>3.0.2</version><type>pom</type></dependency>2.编写实体类,接⼝类与接⼝实现User.javapackage com.itstudy.domain;import javax.xml.bind.annotation.*;@XmlRootElement(name = "User")@XmlAccessorType(XmlAccessType.FIELD)@XmlType(name = "User")public class User {@XmlElement(nillable = true)private Long id;@XmlElement(nillable = true)private String name;@XmlElement(nillable = true)private int age;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}HelloService.javapackage com.itstudy.service;import er;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebService;import java.util.List;@WebServicepublic interface HelloService {@WebMethodpublic String say(@WebParam(name="name")String name);@WebMethodpublic String sayHello(@WebParam(name="user") User user);@WebMethodpublic List<User> getList(Long id);}HelloServiceImpl.javapackage com.itstudy.service.impl;import er;import com.itstudy.service.HelloService;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import java.util.ArrayList;import java.util.List;@WebServicepublic class HelloServiceImpl implements HelloService {@WebMethodpublic String say(@WebParam(name = "name") String name) {return name + ",您好!";}@WebMethodpublic String sayHello(@WebParam(name = "user") User user) {return user.getName() + ",您好!";}@WebMethodpublic List<User> getList(Long id) {List<User> list = new ArrayList<User>();User user = new User();Long sid = 1L;user.setId(sid);user.setName("张三" + sid);list.add(user);user = new User();sid = 2L;user.setId(sid);user.setName("张三" + sid);list.add(user);return list;}}3.启动服务package com.itstudy;import com.itstudy.service.HelloService;import com.itstudy.service.impl.HelloServiceImpl;import org.apache.cxf.jaxws.JaxWsServerFactoryBean;public class App {public static void main(String[] args) {//启动⽅式1 此⽅式接⼝实现必须添加注解 @WebService @WebMethod等// System.out.println( "Hello World!" );// HelloServiceImpl implementor = new HelloServiceImpl();// String address = "http://localhost:8080/ws/" + HelloService.class.getSimpleName(); // Endpoint.publish(address, implementor);//启动⽅式2 此⽅式接⼝实现不需要添加注解JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();factory.setServiceClass(HelloService.class);// 发布接⼝factory.setAddress("http://localhost:8080/ws/" + HelloService.class.getSimpleName()); factory.setServiceBean(new HelloServiceImpl());factory.create(); //发布多个接⼝,多定义⼏个factory即可}}4.动态调⽤webservicepackage com.itstudy;import org.apache.cxf.endpoint.Client;import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;public class HelloWorldClient {public static void main(String[] argv) {JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); Client client =dcf.createClient("http://localhost:8080/ws/HelloService?wsdl");//sayHello为接⼝中定义的⽅法名称张三为传递的参数返回⼀个Object数组Object[] objects = new Object[0];try {objects = client.invoke("getList", 1L);} catch (Exception e) {e.printStackTrace();}//输出调⽤结果System.out.println(objects[0]);}}总结1.两种创建⽅式 1.1 JaxWsServerFactoryBean启动(接⼝实现不需要相关注解) 1.2 Endpoint启动 (接⼝实现与需要相关注解)2.三种调⽤⽅式 2.1动态代理 2.2拿到现有接⼝与类 2.3⽣成相关代理类参考⽂档cxf 发布多个接⼝https:///qq_21399933/article/details/78818240cxf 三种发布⽅式与4种调⽤⽅式https:///u011498933/article/details/75355338cxf 客户端调⽤2https:///z69183787/article/details/53488887cxf 客户端调⽤3https:///nba/blog/482117cxf 安全认证1https:///rangqiwei/article/details/19282271cxf 安全认证2https:///weixin_41138656/article/details/79393366cxf实战创建webservice 与创建restfulapihttps:///kongxx/article/details/7534035。
CXF框架实现Webservice服务——于2015年02月05日Apache CXF是一种基于Servlet技术的SOA应用开发框架。
CXF 继承了Celtix 和XFire 两大开源项目的精华,提供了对多种Web Services 标准的支持,包含SOAP、Basic Profile、WS-Addressing等。
CXF允许根据实际项目的需要,采用代码优先(Code First)或者WSDL 优先(WSDL First)来实现Web Services应用的发布和使用。
一、SOA架构与Webservice1.1 SOA架构的产生SOA(Service-oriented architecture) 面向服务的体系结构,是构造分布式系统应用程序的方法。
它将应用程序功能作为服务发送给最终用户或者其他服务,采用开放标准、与软件资源进行交互并采用表示的标准方式。
SOA架构思想的产生源于两个方面:需求拉动和技术推动。
(1) 需求拉动需求拉动方面,主要来自于两种信息化的困境。
一个是“信息孤岛”造成基于系统之间互联互通的整合需求;另一个是业务的变化所导致对IT灵活性,以适应变化的需求。
企业在不同的时期和不同的厂商合作,建立了不同的应用系统,而系统之间彼此互不关联。
因此导致企业内部各个系统成为一个“信息孤岛”,造成信息不一致。
同时,系统的互联互通不仅包含一个企业内部,也包括集团和各个分公司系统之间的互通。
另一方面,由于行业竞争的日益激烈,企业需要不断地调整自身的业务流程,而僵化的IT基础设施跟不上这种不断加快的变化。
传统的信息化方法和软件研究方法是对业务需求的直接映射,这种“需求驱动”的信息系统最大的缺陷就是对变化的适应性差,因此需要一种按照架构驱动,对业务进行适当的抽象,通过服务的表达和业务过程的原子化,来满足系统是按照企业架构来构造,这种架构是动态重构技术来支撑的,这种架构就是SOA。
(2) 技术推动造成系统之间不能互联互通的一个重要原因,就是系统的异构性。
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,很不⽅便,如果同⼀个项⽬中则没有区别。
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描述信息输出了,说明服务已经发布了。
使用Spring+CXF开发WebServiceApache CXF 提供方便的Spring整合方法,可以通过注解、Spring标签式配置来暴露Web Services和消费Web Services各种类型的Annotation。
@WebService和@WebMethod是WSDL映射Annatotion。
这些Annotation将描述Web Service的WSDL文档元素和Java源代码联系在一起。
@SOAPBinding是一个绑定的annotation用来说明网络协议和格式。
1、@WebService annotation的元素name,serviceName和targetNamespace成员用来描述wsdl:portType,wsdl:service,和targetNameSpace生成WebService中的WSDL文件。
2、@SOAPBinding是一个用来描述SOAP格式和RPC的协议的绑定Annotation。
3、@WebMethod Annotation的operationName成员描述了wsdl:operation,而且它的操作描述了WSDL文档中的SOAPAction头部。
这是客户端必须要放入到SQAPHeader中的数值,SOAP 1.1中的一种约束。
4、@WebParam Annotation的partName成员描述了WSDL文档中的wsdl:part。
5、@WebResult Annotation的partName成员描述了wsdl:part用来返回WSDL文档的值。
例如下面使用annotation定义了一个webservice:import java.util.List;import javax.jws.WebMethod;import javax.jws.WebParam;import javax.jws.WebResult;import javax.jws.WebService;import er;@WebService(targetNamespace = "/client") public interface UserService {@WebMethod(operationName="Insert")public void insert( @WebParam(name = "userId") String userid,@WebParam(name = "userName") String username,@WebParam(name = "userEmail") String useremail,@WebParam(name = "userAge") int userage);@WebMethod(operationName="GetUserById")@WebResult(name = "result")public User getUserById(@WebParam(name="userid") String userid);@WebMethod(operationName="GetAllUsers")@WebResult(name = "result")public List getAllUsers();}其实现类如下所示:import java.util.List;import javax.jws.WebService;import erDao;import er;import erService;@WebService(endpointInterface="erService")public class UserServiceImpl implements UserService {private UserDao userDao;public List getAllUsers() {return userDao.findAllUser();}public User getUserById(String userid) {return userDao.findUserById(userid);}public void insert(String userid, String username, String useremail, int userage) {User user=new User();user.setUserage(userage);user.setUseremail(useremail);user.setUserid(userid);user.setUsername(username);userDao.insert(user);System.out.println("insert successfully!");}public void setUserDao(UserDao userDao) {erDao = userDao;}}注意:实现类中的@WebService,其中的endpointInterface成员指定了该类实现的接口在Spring的配置文件中,需要对其进行配置:首先在ApplicationContext.xml(Spring的配置文件)中引入CXF的XML Scheam 配置文件),如下:<beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:jaxws="/jaxws"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /jaxws/schemas/jaxws.xsd"><!—还需要引入以下3个关于CXF的资源文件,这三个文件在cxf.jar中--><import resource="classpath:META-INF/cxf/cxf.xml" /><import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />……………………………………………………</bean>其次就是在Spring的配置文件中配置webservice,如下所示:<jaxws:endpoint id="userManager" address="/UserManager"implementorClass="erService"><jaxws:implementor><bean id="userServiceImpl"class="erServiceImpl"><property name="userDao"><ref bean="userDao" /></property></bean></jaxws:implementor></jaxws:endpoint>注意:①、address 为webservice发布的地址②、implementorClass 为该webservice实现的接口③、<jaxws:implementor></jaxws:implementor>之间定义的是implementorClass指定接口的实现类另外,在Spring的配置文件中配置完成后,需要修改web.xml文件<servlet><servlet-name>CXFServlet</servlet-name><servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class></servlet><servlet-mapping><servlet-name>CXFServlet</servlet-name><url-pattern>/services/*</url-pattern></servlet-mapping>注意<url-pattern>/ services /*</url-pattern>配置,CXFServlet会拦截此类url,进行处理。
上面配置的webservice将通过如下URL访问到:http://localhost:8080/cxf-ws/services/UserManager UserManager为<jaxws:endpoint >标签中address属性对应的值cxf-ws为本项目的名称配置完成之后,将项目部署到tomcat上输入URL:http://localhost:8080/cxf-ws/services/UserManager?wsdl将会看到生成的wsdl文件为了能够直接访问到erService中的insert方法,进行如下测试:创建一个insertUser.html页面:<html><head><script type="text/javascript">function post() {var xmlhttp=false;if (!xmlhttp && typeof XMLHttpRequest!='undefined') {try {xmlhttp = new XMLHttpRequest();} catch (e) {xmlhttp=false;}}if (!xmlhttp && window.createRequest) {try {xmlhttp = window.createRequest();} catch (e) {xmlhttp=false;}}var dest = document.getElementById('destination').value;xmlhttp.open("POST", dest, true);xmlhttp.onreadystatechange=function() {if (xmlhttp.readyState==4) {document.getElementById("result").innerHTML = xmlhttp.responseText;}}xmlhttp.setRequestHeader("Man", "POST " + dest + " HTTP/1.1")xmlhttp.setRequestHeader("MessageType", "CALL")xmlhttp.setRequestHeader("Content-Type", "text/xml");var texta = document.getElementById('texta');var soapmess = texta.value;xmlhttp.send(soapmess);}</script></head><body>hi there<form id="forma"><textarea id="texta" rows="10" cols="80"><?xml version='1.0' encoding='UTF-8'?><SOAP-ENV:Envelopexmlns:SOAP-ENV="/soap/envelope/"xmlns:xsi="/1999/XMLSchema-instance"xmlns:xsd="/1999/XMLSchema"><SOAP-ENV:Body><Insert><userId>2005221104210066</userId><userName>Leon Cao</userName><userEmail>caohongliang2@</userEmail><userAge>23</userAge></Insert></SOAP-ENV:Body></SOAP-ENV:Envelope></textarea><p><input type="text" id="destination" size="50"value="http://localhost:8080/cxf-ws/services/UserManager"></input> <p><input type="button" onclick="post()" name="submit"value="Submit"></input></form><div id="container"></div>Result:<hr><div id="result"></div><hr><div id="soap"></div></body></html>在该测试页面需要注意标记为红色的部分,如下是一个soap message:<?xml version='1.0' encoding='UTF-8'?><SOAP-ENV:Envelopexmlns:SOAP-ENV="/soap/envelope/"xmlns:xsi="/1999/XMLSchema-instance"xmlns:xsd="/1999/XMLSchema"><SOAP-ENV:Body><Insert><userId>2005221104210066</userId><userName>Leon Cao</userName><userEmail>caohongliang2@</userEmail><userAge>23</userAge></Insert></SOAP-ENV:Body></SOAP-ENV:Envelope>注意:①<SOAP-ENV:Body>标签之间<Insert>对应@WebMethod(operationName="Insert") 中的operationName属性的值②<userId>、<userName>、<userEmail>、<userAge>标签对各自对应着insert方法中 @WebParam中name属性的值:@WebParam(name = "userId") String userid,@WebParam(name = "userName") String username,@WebParam(name = "userEmail") String useremail,@WebParam(name = "userAge") int userage);当向webservice上发送该soap消息的时候将自动解析该soap消息,将Insert解析为insert方法,将<userId>、<userName>、<userEmail>、<userAge>标签对之间的值解析为相对应的参数userid、username、useremail、userage③<input type="text" id="destination" size="50"value="http://localhost:8080/cxf-ws/services/UserManager"></input>该文本标签中的value属性为webservice的地址运行该页面,点击Submit后将在数据库中插入一行数据,即调用了inser方法成功。