springboot集成CXF开发webservice,并向外发布,调用接口

先复制一段说明:      

      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.依赖

<dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-spring-boot-starter-jaxws</artifactId>
            <version>3.2.7</version>
        </dependency>

2.要向外发布的接口

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;

/**
 * <p>
 * 51job招聘信息表 服务类
 * </p>
 *
 * @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;

/**
 * <p>
 * 51job招聘信息表 服务实现类
 * </p>
 *
 * @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对外接口的发布以及远程调用外部接口。非常简单!

猜你喜欢

转载自blog.csdn.net/weixin_46792649/article/details/106983499