用CXF开发RESTful风格WebService
- 格式:doc
- 大小:162.50 KB
- 文档页数:9
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⽣成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.。
用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中文版》一书。
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 开发。
基于CXF的RESTful Web Service访问服务研究陈铁【摘要】REST(Representational State Transfer)表述性状态转移是目前比较流行的Web Service架构风格,为软件设计定义了一组架构约束和原则.REST的Java 实现框架众多,CXF集成了Celtix XFire两个开源框架,使得开发Web service的工作变得更加简单、灵活.文章介绍CXF的基本概念、系统架构,并对CXF的功能模块和实现原理进行了较为详细的介绍.【期刊名称】《现代制造技术与装备》【年(卷),期】2017(000)008【总页数】2页(P32-33)【关键词】REST;CXF;RESTful Web Service;Spring MVC【作者】陈铁【作者单位】武汉软件工程职业学院,武汉430205【正文语种】中文REST是Roy Thomas Fielding博士于2000年在他的博士毕业论文中首次提出,中文翻译为表述性状态转移。
它是一种简单、灵活的架构风格,主要思想是基于Http构建数据访问接口。
REST的所有操作均是无状态的,针对不同的访问请求、数据提供统一的接口,并返回Json、XML等格式的数据。
目前,有多种基于Java的restful web servie实现方式,比较流行的包括Rails、Axis2、JAX-RS、Restlet、CXF等。
其中,CXF是一种轻量级的Restful实现框架,其已经成为Apache的顶级项目,可以方便地与各种MVC框架结合使用,为企业级应用系统提供安全、可靠的数据支持。
1.1 概述CXF是Apache下的一个顶级SOA简单架构,实现了企业服务总线ESB框架和设计模式。
CXF是两个开源项目Celtix和XFire结合的产物,极大的融合了二者的优点。
CXF提供多种技术支持,包括web Servivce架构JAX-WS的支持,并支持Binding、DataBing等功能模块的实现。
使用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,进行处理。
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) 技术推动造成系统之间不能互联互通的一个重要原因,就是系统的异构性。
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发布restful WebService的入门例子实现用HTTP请求对以上资源的CRUD。
首先建立room,person的POJO,这里只有一点需要注意:package com.DAO;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name="Person")public class Person {private String name;private String sex;public String getName() {return name;}public void setName(String name) { = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}}一定要在类的前边加上annotation ,这样才能让这个person的信息在POJO和XML之间转换。
Room同理:import java.util.Map;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name="Room")public class Room {public Room(){persons=new HashMap<String,Person>();}String id;Map<String,Person> persons;public String getId() {return id;}public void setId(String id) {this.id = id;}public Map<String, Person> getPersons() {return persons;}public void setPersons(Map<String, Person> persons) {this.persons = persons;}}POJO有了,接下来要写DAO,由于主要是为了学习restful,为了方便,不必要将数据持久化到数据库,而是存在一个静态的HashMap中:package com.DAO;import java.util.HashMap;import java.util.Map;public class RoomDAO {private static Map<String, Room> rooms;static {rooms = new HashMap<String, Room>();Person p1=new Person();p1.setName("Boris");p1.setSex("male");Room r=new Room();r.setId("001");r.getPersons().put(p1.getName(), p1);rooms.put("001", r);}public static void addRoom(Room room) {rooms.put(room.getId(), room);}public static void deleteRoom(String id) {if (rooms.containsKey(id)) {rooms.remove(id);}}public static void updateRoom(String id,Room room) { rooms.remove(id);rooms.put(room.getId(), room);}public static Room getRoom(String id) {if (rooms.containsKey(id)) {return rooms.get(id);} else {return null;}}/*operations to persons*/public static void addPerson(String id_room,Person person) { if(rooms.containsKey(id_room)){Room room=rooms.get(id_room);room.getPersons().put(person.getName(), person);}}public static Rooms getRooms(){return new Rooms();}public static void deletePerson(String id_room,String name) {if(rooms.containsKey(id_room)){Room room=rooms.get(id_room);room.getPersons().remove(name);}}public static Map<String, Room> getMapOfRooms(){return rooms;}接下来是重点,如果想发布restful webservice,要通过一个叫JAXRSServerFactoryBean的类来发布。
用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中文版》一书。
下面以开发一个普通接口和开发REST风格WebService接口为对比,指导大家快速入门。
2开发一个普通的接口
2.1定义DTO
2.2定义接口
2.3实现类
接口的实现,就此省略。
3开发RESTful风格WebService服务端3.1定义资源(定义DTO)
之间的互相转换。
不熟悉JAXB规范的可以自行搜索相关资料。
此Info对象对应的XML格式如下:
3.2开发接口
表示响应/.../infos的GET请求,返回Info列表。
表示响应
对应的Info
表示响应
格式,最终保存Info对象。
表示响应
删除对应的Info
3.3实现类
接口的实现,同上。
3.4配置CXF(整合Spring)
3.4.1接口的Spring配置文件
定义接口的实现类
3.4.2CXF的Spring配置文件
强烈建议加前缀!以此来提供不同版本的WebService访问!
3.4.3修改web.xml
到此,配置完毕,可以启动部署到web容器中启动,在FireFox中访问http://localhost:8080/v1/infos,看看是否有XML格式的输出。
4开发RESTful风格WebService客户端(Java)
4.1定义客户端接口
4.2定义实现类
客户端如果能引用服务端的jar包,那么开发将非常简单。
客户端的开发十分简便,如果用其他语言,那么需要自行使用对应的HTTP类库进行编码。
5范例
本文对应的例子为maven构建:
cod-sample-ret为服务端,运行jetty:run即可
rest-client为客户端,运行src/test/java/com/csair/cod/restclient/RestClientTest.java单元测试类即可。