一.前言
说起web service最近几年restful大行其道,大有取代传统soap web service的趋势,但是一些特有或相对老旧的系统依然使用了传统的soap web service,例如银行、航空公司的机票查询接口等。本博客主要讲解得是spring boot整合cxf发布webservice服务和spring boot整合cxf客户端调用webservice服务
本案例使用maven方式
二.编码
核心文件清单
1.pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion><groupId>com.leftso</groupId>
<artifactId>demo-webservice-cxf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging><name>demo-webservice-cxf</name>
<description>Demo project for Spring Boot security</description><parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.5.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent><properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties><dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency><!-- CXF webservice -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.1.7</version>
</dependency>
<!-- CXF webservice --><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies><build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build></project>

2.CommonService.java 服务接口

package com.leftso.webservice;import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;/**
* 接口
*
* @author leftso
*
*/
@WebService(name = "CommonService", // 暴露服务名称
targetNamespace = "http://webservice.leftso.com/"// 命名空间,一般是接口的包名倒序
)
public interface CommonService {
@WebMethod
@WebResult(name = "String", targetNamespace = "")
public String sayHello(@WebParam(name = "userName") String name);}3.接口实现
package com.leftso.webservice;import javax.jws.WebService;import org.springframework.stereotype.Component;/**
* 接口实现
*
* @author leftso
*
*/
@WebService(serviceName = "CommonService", // 与接口中指定的name一致
targetNamespace = "http://webservice.leftso.com/", // 与接口中的命名空间一致,一般是接口的包名倒
endpointInterface = "com.leftso.webservice.CommonService"// 接口地址
)
@Component
public class CommonServiceImp implements CommonService {@Override
public String sayHello(String name) {return "Hello ," + name;
}}4.配置cxf服务发布,默认服务在Host:port/services/***路径下
package com.leftso.config;import javax.xml.ws.Endpoint;import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import com.leftso.webservice.CommonService;@Configuration
public class CxfConfig {
@Autowired
private Bus bus;@Autowired
CommonService commonService;/** JAX-WS **/
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, commonService);
endpoint.publish("/CommonService");
return endpoint;
}
}

  

这里相当于把Commonservice接口发布在了路径/services/CommonService下,wsdl文档路径为http://localhost:8080/services/CommonService?wsdl

创建基于cxf的客服端调用webservice接口(非使用wsdl文档生成java类)

package com.leftso.client;import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;import com.leftso.webservice.CommonService;public class CxfClient {
public static void main(String[] args) {
cl1();
}/**
* 方式1.代理类工厂的方式,需要拿到对方的接口
*/
public static void cl1() {
try {
// 接口地址
String address = "http://localhost:8080/services/CommonService?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(CommonService.class);
// 创建一个代理接口实现
CommonService cs = (CommonService) jaxWsProxyFactoryBean.create();
// 数据准备
String userName = "Leftso";
// 调用代理接口的方法调用并返回结果
String result = cs.sayHello(userName);
System.out.println("返回结果:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}/**
* 动态调用方式
*/
public static void cl2() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:8080/services/CommonService?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME,
// PASS_WORD));
Object[] objects = new Object[0];
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("sayHello", "Leftso");
System.out.println("返回数据:" + objects[0]);
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
}

调用后返回结果输出为
Hello,Leftso

三.问题Q&A
3.1已知问题1
将上面例子的Spring Boot版本升级至1.5.x。启动项目报错:

java.lang.NoClassDefFoundError: org/springframework/boot/context/embedded/ServletRegistrationBean
at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_40]
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_40]
at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_40]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:613) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:524) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:510) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:570) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:697) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:640) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:609) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1484) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:425) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:395) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
at com.leftso.Application.main(Application.java:10) [classes/:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.embedded.ServletRegistrationBean
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_40]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_40]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_40]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_40]
... 23 common frames omitted

解决办法:
出现这个问题的第一时间,我以为是常规的maven管理jar包依赖问题。后面群里有小伙伴多次尝试证明了不是maven的依赖包问题。而是spring boot的版本和cxf的版本不兼容问题。
已知兼容版本:
Spring boot 1.4.x ------>cxf-spring-boot-starter-jaxws 3.1.x
Spring boot 1.5.x------->cxf-spring-boot-starter-jaxws 3.2.x
所以出现上面问题,且用了spring boot 1.5.x的小伙伴请将cxf-spring-boot-starter-jaxws 版本升级到3.2.1即可解决。

3.2修改spring boot cxf整合后默认的/services路径
在spring boot的application配置文件中配置
cxf.path=/yourpath

本文转自:http://www.leftso.com/blog/144.html

转载于:https://www.cnblogs.com/JThinking/p/9487047.html

spring boot整合cxf发布和调用webservice相关推荐

  1. spring boot 整合 谷歌guava的EventBus 实现单机版的消息发布订阅

    spring boot 整合 谷歌guava的EventBus 实现单机版的消息发布订阅 大型分布式系统,直接用mq解耦,那么单机系统怎么办,可以考虑用EventBus 用EventBus的好处也是异 ...

  2. Spring boot整合Redis实现发布订阅(超详细)

    Redis发布订阅 基础知识 相关命令 订阅者/等待接收消息 发布者/发送消息 订阅者/成功接收消息 常用命令汇总 原理 Spring boot整合redis 导入依赖 Redis配置 消息封装类(M ...

  3. spring boot 整合Dubbo/Zookeeper

    spring boot 整合Dubbo/Zookeeper 只是一个简单的整合demo,只做思路分析叙述,具体功能不做描述. 一.技术介绍 •ZooKeeper ZooKeeper 是一个分布式的,开 ...

  4. Spring Boot整合Shiro + JSP教程(用户认证,权限管理,图片验证码)

    在此首先感谢**编程不良人**up主提供的视频教程 代码都是跟着up的视频敲的,遇到的一些问题也是通过CSDN博主提供的教程解决的,在此也感谢那些提供bug解决方案的前辈们~ 项目完整代码已经发布到g ...

  5. Spring Boot整合ActiveMQ及场景举例(点对点模式、订阅模式)

    目录 前序 为什么要引入MQ 注册案例--不使用MQ 注册案例--引入MQ(点对点模式) 注册案例--引入MQ(发布/订阅模式) 安装Active MQ 使用Spring Boot进行整合(点对点模式 ...

  6. 用cxf发布和调用web service

    用cxf发布和调用web service http://cxf.apache.org/docs/jax-ws-configuration.html  官方API helloword地址 用CXF来做w ...

  7. Spring Boot 使用Redis发布订阅模式处理消息

    Spring Boot 使用Redis发布订阅模式 1. Redis发布订阅模式 2. Spring Boot中订阅消息 2.1 Redis监听器容器配置 2.2 创建通道监听器 2.3 测试订阅功能 ...

  8. Spring Boot: Spring Boot 整合 RabbitMQ

    前言 RabbitMQ 是一个消息队列,说到消息队列,大家可能多多少少有听过,它主要的功能是用来实现应用服务的异步与解耦,同时也能起到削峰填谷.消息分发的作用. 消息队列在比较主要的一个作用是用来做应 ...

  9. Spring Boot整合elasticsearch实现全文检索

    文章目录 1.引入 1.1 Luence 1.2 Solr 1.3 ElasticSearch 2. ElasticSearch安装 2.1 云服务器安装 2.1.1. docker安装 2.1.2 ...

最新文章

  1. 书单 | 春日必读书,少看一本都是遗憾
  2. mongodb 对内存的占用监控 ——mongostat,linux系统可用的内存是free + buffers + cached...
  3. python爬虫获取的网页数据为什么要加[0-Python爬虫实战1-解决需要爬取网页N秒后的内容的需求...
  4. python command line debug_【已解决】Mac中PyCharm中去加断点实时调试scrapy的项目
  5. 6种Python字符串反转方式
  6. 【Eclipse】Java Compiler没有Annotaion Processing, 需要安装Eclipse Java Development Tools
  7. 高性能nginx HTTP服务器 配置实例(转自我的收藏)
  8. 【codevs1227】方格取数2,费用流
  9. 广西全国计算机二级考试内容,全国高校计算机等级考试(广西考区)二级考试大纲.doc...
  10. “苹果正在走下神坛” | 畅言
  11. 拉格朗日中值定理ξ怎么求_微分学核心定理——中值定理
  12. 高速串行总线走线难点在哪?重要线信号的处理经验分享
  13. [Linux学习]更改默认启动图形界面或命令行
  14. PHP 将文字转化mp3文件
  15. ETL数据抽取 全量 增量
  16. 百度网站诚信认证现在是个什么情况呢?
  17. html合并边框线,css中border-collapse属性设置表格边框线的方法
  18. 身份证有效验证方法,
  19. 对有序表进行折半查找的非递归算法
  20. 微信公众号模板如何使用?公众号模板教程!

热门文章

  1. C语言系列之自增自减运算符的用法(二)
  2. MySQL安装与操作总结
  3. 1201-统计数字问题
  4. 算法题003 斐波那契(Fibonacci)数列
  5. (进阶)LeetCode(9)——回文数(JavaScript)
  6. 【Vue】—Vue拆分文件
  7. jQuery学习(三)—jQuery使用步骤以及注意事项
  8. oracle11.2.03,升级Oracle11.2.0.3后遭遇ORA-00600[kfioTranslateIO03][17090]
  9. 支撑位和压力位怎么看是什么意思?
  10. 如何安装TrueNAS