前段时间业务需求正好做了这方面的,自己整理下正好相当于做一份文档记录
CXF(Celtix + XFire),支持SOAP、XML/HTTP、RESTful HTTP 或者 CORBA等多协议的service服务 ,优先支持WSDL模式,在互联网公司很难见到,但是在一些比较早期的HTTP通讯业务里,可以说很常见,废话不多说,直接开始
第一步,需要自建一个springboot2的maven工程,引入webservice需要的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.2.6</version>
</dependency>
注意:对springboot版本有限制
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<!--之后版本弃掉了CXFServlet-->
<!--<version>2.1.4.RELEASE</version>-->
</parent>
第二步:创建webService服务端
1.创建接口(创建User对象略)
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(targetNamespace = "http://service.wjx.com")
public interface UserService {
@WebMethod
User getUser(@WebParam(name="userId") String userId);
@WebMethod
@WebResult(name="String",targetNamespace = "")
String getUserName(@WebParam(name="userId") String userId);
}
2创建实现类
import javax.jws.WebService;
import java.util.HashMap;
import java.util.Map;
@WebService(
serviceName = "UserService", //对外发布的服务名
targetNamespace = "http://service.wjx.com", //名称空间,包的反转
endpointInterface = "com.wjx.service.UserService" //服务接口全路径
)
public class UserServiceImpl implements UserService {
private Map<String, User> userMap = new HashMap<String, User>();
@override
实现方法
}
主要使用常用的webservice注解的集中常见的方式,基本了解其功能和用法
4配置其配置项
做到这一步下面的思路应该是如何将我们写的webService信息发布出去,cxf提供了EndpointImpl对象,并且提供了
publish来推送服务
如何构造这个类呢,API提供如下
需要一个BUS(消息总线,服务接口,切入点信息)
首先我们使用@Bean方法注入BUS对象(这个也可以在org.apache.cxf.bus.spring中找到)
@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
return new SpringBus();
}
然后我们需要一个接口对象
@Bean
public UserService userService() {
return new UserServiceImpl();
}
EndpointImpl信息在写webService注解时已经提供给了
最后尝试@Bean注入()
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(springBus(), userService());
endpoint.publish("/user");
return endpoint;
}
第三步:完善功能
启动项目后,访问wsdl路径,发现
405错误,表示浏览器不支持此种请求方式,如何解决呢?
这里参考了git上其他人的代码,@Bean注入了个ServletRegistrationBean对象
@Bean
public ServletRegistrationBean<CXFServlet> dispatcherServlet() {
return new ServletRegistrationBean<CXFServlet>(new CXFServlet(),"/soap/*");
}
将CXFServlet对象注入到Servlet注册容器中,使Servlet对象支持CXF模式
简单服务端完成!
第四步:创建客户端
1反向生成客户端代码
方法有很多种,最常见的是wsimport 命令模式,或者直接使用idea工具,这里我就直接在项目里直接用(实际项目肯定是分开服务端和实现端的)
2编写mian调用main1方法
public static void main1() {
try {
// 接口地址
String address = "http://127.0.0.1:8080/soap/user?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(UserService.class);
// 创建一个代理接口实现
UserService us = (UserService) jaxWsProxyFactoryBean.create();
// 数据准备
String userId = "111111";
// 调用代理接口的方法调用并返回结果
String userName = us.getUserName(userId);
User user = us.getUser(userId);
System.out.println("用户名:" + userName);
System.out.println("用户:" + user);
} catch (Exception e) {
e.printStackTrace();
}
}
测试结果如下: