先复制一段说明:
Apache CXF = Celtix + XFire,CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或 者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。
CXF 包含了大量的功能特性,但是主要集中在以下几个方面:
1.支持 Web Services 标准:CXF 支持多种 Web Services 标准,包含 SOAP、Basic Profile、WS-Addressing、WS-Policy、WS-ReliableMessaging 和 WS-Security。
2.Frontends:CXF 支持多种“Frontend”编程模型,CXF 实现了 JAX-WS API (遵循 JAX-WS 2.0 TCK 版本),它也包含一个“simple frontend”允许客户端和 EndPoint 的创建,而不需要 Annotation 注解。CXF 既支持 WSDL 优先开发,也支持从 Java 的代码优先开发模式。
3.容易使用: CXF 设计得更加直观与容易使用。有大量简单的 API 用来快速地构建代码优先的 Services,各种 Maven 的插件也使集成更加容易,支持 JAX-WS API ,支持 Spring 2.0 更加简化的 XML 配置方式,等等。
支持二进制和遗留协议:CXF 的设计是一种可插拨的架构,既可以支持 XML ,也可以支持非 XML 的类型绑定,比如:JSON 和 CORBA。
以下手撸:
拿我以前爬的51job数据做个简单的例子,举一反三
1.依赖
org.apache.cxf
cxf-spring-boot-starter-jaxws
3.2.7
2.要向外发布的接口
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
/**
*
* 51job招聘信息表 服务类
*
*
* @author xrj
* @since 2019-12-13
*/
@WebService(targetNamespace = "http://service.webservice.xr.com")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface QcpageService {
@WebMethod
String getStrXrj(@WebParam(name="str") String str);
}
实现类:
import com.xr.webservice.service.QcpageService;
import com.xr.webservice.dao.QcpageMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.jws.WebService;
/**
*
* 51job招聘信息表 服务实现类
*
*
* @author xrj
* @since 2019-12-13
*/
//serviceName:要发布的服务名,targetNamespace:命名空间,一般为包名倒序,endpointInterface:接口路径
@Service
@WebService(serviceName = "QcpageService",targetNamespace = "http://service.webservice.xr.com", endpointInterface = "com.xr.webservice.service.QcpageService")
public class QcpageServiceImpl implements QcpageService {
@Autowired
QcpageMapper qcpageMapper;
@Override
public String getStrXrj(String str) {
return str+"----webservice接口开发";
}
}
这里注意:接口类和实现类上Webservice注解的targetNamespace属性必须要一样,否则在远程调用的时候会出现以下报错,踩坑啦:
No operation was found with the name {http://service.webservice.xr.com}getStrXrj.
发布配置:
import com.xr.webservice.service.QcpageService;
import org.apache.cxf.Bus;
import org.apache.cxf.bus.spring.SpringBus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class CxfConfig {
@Autowired
private QcpageService qcpageService;
@Autowired
private Bus bus;
//此处注释后,访问地址为: http://localhost:9999/service/qcpagewebservice?wsdl
//放开注释后,访问地址为:http://localhost:9999/qcpagewebservice/qcpagewebservice?wsdl
@Bean(name= "cxfServlet")
public ServletRegistrationBean dispatcherServlet(){
return new ServletRegistrationBean(new CXFServlet(),"/qcpagewebservice/*");
}
@Bean(name=Bus.DEFAULT_BUS_ID)
public SpringBus springBus(){
return new SpringBus();
}
/**
* 注册QcpageService 接口到webservice服务
* @return
* 浏览器访问地址 http://localhost:9999/qcpagewebservice/qcpagewebservice?wsdl
*
*/
@Bean
public Endpoint endpointHelloService(){
EndpointImpl endpoint=new EndpointImpl(bus,qcpageService);
endpoint.publish("/qcpagewebservice");
return endpoint;
}
}
访问结果:
另外,我在另一个项目中创建客户端:
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
public class CxfClient {
public static void main(String[] args) {
CxfClient.main2();
}
/**
* 1.代理类工厂的方式,需要拿到对方的接口地址,不建议,需要考虑服务端的实现
*/
// public static void main1() {
// try {
// // 接口地址
// String address = "http://localhost:9999/qcpagewebservice/qcpagewebservice?wsdl";
// // 代理工厂
// JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
// // 设置代理地址
// jaxWsProxyFactoryBean.setAddress(address);
// // 设置接口类型
// jaxWsProxyFactoryBean.setServiceClass(QcpageService.class);
// // 创建一个代理接口实现
// QcpageService us = (QcpageService) jaxWsProxyFactoryBean.create();
// // 数据准备
// String userId = "maple";
// // 调用代理接口的方法调用并返回结果
// String result = us.getStrXrj("xingrenjie");
// System.out.println("返回结果:" + result);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
/**
* 2:动态调用,无需考虑服务端的实现
*/
public static void main2() {
// 创建动态客户端
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost:9999/qcpagewebservice/qcpagewebservice?wsdl");
// 需要密码的情况需要加上用户名和密码
// client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
Object[] objects = new Object[0];
try {
// invoke("方法名",参数1,参数2,参数3....);
objects = client.invoke("getStrXrj", "xingrenjie");
System.out.println("返回数据:" + objects[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
以下是远程调用结果:
返回数据:xingrenjie----webservice接口开发
到这里就完事儿了,使用CXF对外接口的发布以及远程调用外部接口。非常简单!