SpringBoot整合cxf开发WebService
Apache CXF一个开源的Service框架,它实现了JCP与Web Service中一些重要标准。CXF简化了构造,集成,面 向服务架构(SOA)业务组件与技术的灵活复用。在CXF中,Service使用WSDL标准定义并能够使用各种不同的消息 格式(或binding)和网络协议(transports)包括SOAP、XML(通过HTTP或JMS)进行访问。CXF同样支持多种model 如:JAX-WS,JBI,SCA和CORBA service。CXF设计成可灵活部署到各种容器中包括Spring-based,JBI,SCA, Servlet和J2EE容器。
服务端代码
1.引入依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- CXF Restful webservice -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxws</artifactId>
<version>3.2.4</version>
<exclusions>
<!--The Bean Validation API is on the classpath but no implementation could be found-->
<exclusion>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
2.服务的发布
/**
* 自动发布接口地址注解
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoPublish {
/**
* 发布地址
*/
String publishAddr();
}
@Component
public class PublishEndpoint implements ApplicationRunner {
@Autowired
private WebApplicationContext applicationConnect;
@Autowired
@Qualifier(Bus.DEFAULT_BUS_ID)
private SpringBus bus;
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("开始进行自动发布webService接口");
String[] beanNames = applicationConnect.getBeanNamesForAnnotation(AutoPublish.class);
for (String beanName : beanNames) {
String publishAddr = applicationConnect.getType(beanName).getAnnotation(AutoPublish.class).publishAddr();
EndpointImpl endpoint = new EndpointImpl(bus, applicationConnect.getBean(beanName));
endpoint.publish(publishAddr);
System.out.println(String.format("发布接口地址:[%s]", publishAddr));
}
System.out.println("weBservice接口自动发布结束");
}
}
3.application.properties
server.port=8080
server.servlet.context-path=/demo
cxf.path=/cxf
4.新增服务接口
package com.example.demo.service;
@WebService
public interface IWebServiceTest {
/**
* webService测试接口
*/
@WebMethod
String getUserService(@WebParam(name = "name") String name);
}
5.新增服务接口实现类
package com.example.demo.service.impl;
@AutoPublish(publishAddr = "/iWebServiceTest")
@WebService(targetNamespace = "http://service.demo.example.com/")
@Component
public class IWebServiceTestImpl implements IWebServiceTest {
@Override
public String getUserService(String name) {
return name + ",getUserService";
}
}
6.验证服务发布
通过浏览器访问wsdl,wsdl路径即为发布的路径加上?wsdl
http://[127.0.0.1]:[端口号]/[server.servlet.context-path]/[cxf.path]/[@AutoPublish(publishAddr = "/iWebServiceTest")]?wsdl
例子:http://127.0.0.1:8080/demo/cxf/iWebServiceTest?wsdl
SoapUi工具测试接口,不要用localhost
客户端代码
/**
* 模拟客户端访问测试
* 使用httpClient访问
*/
public class ClientTest {
public static void main(String[] args) {
// 方式1:代理类工厂的方式,需要拿到对方的接口
proxyFactoryMain();
// 方式2:动态调用方式
dynamicCallMain();
}
/**
* 方式1:代理类工厂的方式,需要拿到对方的接口
*/
public static void proxyFactoryMain() {
try {
// 接口地址
String address = "http://127.0.0.1:8080/demo/cxf/IWebServiceTest?wsdl";
// 代理工厂
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// 设置代理地址
jaxWsProxyFactoryBean.setAddress(address);
// 设置接口类型
jaxWsProxyFactoryBean.setServiceClass(IWebServiceTest.class);
// 创建一个代理接口实现
IWebServiceTest cs = (IWebServiceTest) jaxWsProxyFactoryBean.create();
// 数据准备
String userName = "Darby_";
// 调用代理接口的方法调用并返回结果
String result = cs.getUserService(userName);
System.out.println("返回结果:" + result);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 方式2:动态调用方式
*/
public static void dynamicCallMain() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://127.0.0.1:8080/demo/cxf/IWebServiceTest?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
try {
// invoke("方法名",参数1,参数2,参数3....);
Object[] objects = client.invoke("getUserService", "Darby_");
System.out.println("返回数据:" + objects[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}