Spring boot 整合CXF开发web service示例
前言
说起webservice最近几年restful大行其道,大有取代传统soapwebservice的趋势,但是一些特有或相对老旧的系统依然使用了传统的soapwebservice,例如银行、航空公司的机票查询接口等。
目前就遇到了这种情况,需要在系统中查询第三方提供的soapwebservice接口,也就是说要将它整合进现有的系统当中。
spring整合CXF本来十分简单,但是因为使用了Springboot,不想用以前xml一堆配置的方式,那么能否按照Springboot的风格优雅的进行整合呢?
答案当然是肯定的,但是遍查网上几乎没有这方面的资料,折腾过后觉得还是有必要记录一下,虽然它显得非常的简单。
添加依赖
Maven的项目,首先当然是添加依赖了,除了原先Springboot的依赖之外,还需要添加cxf依赖:
org.apache.cxf cxf-rt-frontend-jaxws 3.1.6 org.apache.cxf cxf-rt-transports-http 3.1.6
编写业务代码
这里我们以查询用户信息为例,创建一个自定义的User对象:
publicclassUserimplementsSerializable{ privatestaticfinallongserialVersionUID=-5939599230753662529L; privateLonguserId; privateStringusername; privateStringemail; privateDategmtCreate; //gettersetter...... }
接下来创建一个用于提供webservice服务的用户接口,共两个方法getName和getUser,一个返回普通的String,一个返回自定义对象:
@WebService publicinterfaceUserService{ @WebMethod StringgetName(@WebParam(name="userId")LonguserId); @WebMethod UsergetUser(LonguserId); }
有接口当然要有业务代码实现了,这里我们只做简单的演示:
publicclassUserServiceImplimplementsUserService{ privateMapuserMap=newHashMap (); publicUserServiceImpl(){ Useruser=newUser(); user.setUserId(10001L); user.setUsername("liyd1"); user.setEmail("liyd1@qq.com"); user.setGmtCreate(newDate()); userMap.put(user.getUserId(),user); user=newUser(); user.setUserId(10002L); user.setUsername("liyd2"); user.setEmail("liyd2@qq.com"); user.setGmtCreate(newDate()); userMap.put(user.getUserId(),user); user=newUser(); user.setUserId(10003L); user.setUsername("liyd3"); user.setEmail("liyd3@qq.com"); user.setGmtCreate(newDate()); userMap.put(user.getUserId(),user); } @Override publicStringgetName(LonguserId){ return"liyd-"+userId; } @Override publicUsergetUser(LonguserId){ returnuserMap.get(userId); } }
发布服务
接口和业务代码我们都写完了,剩下的就是发布服务了,也就是Springboot和cxf的整合。
其实这二者的整合十分的简单,比以前xml的方式更加的简洁,所有相关的代码如下:
@Configuration publicclassCxfConfig{ @Bean publicServletRegistrationBeandispatcherServlet(){ returnnewServletRegistrationBean(newCXFServlet(),"/soap/*"); } @Bean(name=Bus.DEFAULT_BUS_ID) publicSpringBusspringBus(){ returnnewSpringBus(); } @Bean publicUserServiceuserService(){ returnnewUserServiceImpl(); } @Bean publicEndpointendpoint(){ EndpointImplendpoint=newEndpointImpl(springBus(),userService()); endpoint.publish("/user"); returnendpoint; } }
可以看到从配置cxf到发布服务,都只需要一二行代码,出乎意料的简单吧?
到这里我们所有的操作就都完成了,启动Springboot,访问http://localhost:8080/soap/user?wsdl
可以看到有相关的wsdl描述信息输出了,说明服务已经发布了。
调用服务
发布了webservice服务,那怎么调用呢,像整合一些第三方接口也是先有调用才后有发布啊?
调用soapwebservice,一般的方法是根据wsdl生成客户端代码,整合之后就可以像调用本地接口一样使用了。
但是我个人不怎么喜欢这种方式,每个接口都要生成一次还有一堆的代码,感觉比较麻烦。
相对更喜欢传入方法名调用的方式,显得清爽而简洁,以下就是所有代码了:
JaxWsDynamicClientFactorydcf=JaxWsDynamicClientFactory.newInstance(); Clientclient=dcf.createClient("http://localhost:8080/soap/user?wsdl"); Object[]objects=client.invoke("getUser",10002L); //输出调用结果 System.out.println(objects[0].getClass()); System.out.println(objects[0].toString());
这种方式要注意的就是,如果调用的服务接口返回的是一个自定义对象,那么结果Object[]中的数据类型就成了这个自定义对象(组件帮你自动生成了这个对象),
但是你本地可能并没有这个类,所以需要自行转换处理,最简单的是新建一个跟返回结果一模一样的类进行强转,当然更好的方式是封装一个通用的,这个不是本文主题就不在这深入讨论了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。