webService学习(七)CXF框架集合spring boot

1、CXF框架:

Apache CXF一个开源的Service框架,CXF简化了构造,集成,面向服务架构(SOA)业务组件与技术的灵活复用。在CXF中,Service使用WSDL标准定义并能够使用各种不同的消息格式(或binding)和网络协议(transports)包括SOAP、XML(通过HTTP或JMS)进行访问。支持多种协议SOAP、POST/HTTP、RESTful、HTTP等。

CXF是一个实现SOA思想框架,依赖spring,核心是org.apache.cxf.Bus(总线),类似于Spring的 ApplicationContext

内置了Jetty是一个serlvet容器。

 

2、CXF特点:

(1)可以和spring、servlet无缝对接

(2)可以用注解方式来发布webService(@WebService

(3)能够添加输入、输出拦截器(日志形式,便于观察输入输出)

 

3、CXF结合springboot发布服务

(1)添加依赖:

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

(2)先创建一个实体User:

package com.test.cxfdemo.dao;

import java.io.Serializable;

/**
 * @author yanghao
 * @Description:
 * @date 2018/11/6 9:39
 */
public class User implements Serializable{
    private static final long serialVersionUID = -3628469724795296287L;

    private String userId;
    private String userName;
    private String email;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId='" + userId + '\'' +
                ", userName='" + userName + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}

 

(3)写服务端接口UserService,以及实现代码UserServiceImpl:

接口UserService:

package com.test.cxfdemo.Impl;

import com.test.cxfdemo.dao.User;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.soap.Addressing;

/**
 * @author yanghao
 * @Description:
 * @date 2018/11/6 9:44
 */

@WebService(name = "UserService",
        targetNamespace = "http://www.impl.cxfdemo.test.com")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
@Addressing(enabled = true)
public interface UserService {

    @WebMethod  标注该方法为webservice暴露的方法,用于向外公布,它修饰的方法是webservice方法,去掉也没影响的,类似一个注释信息
    User getUser(@WebParam(name = "userId") String userId);

    @WebMethod
    @WebResult(name = "String", targetNamespace = "")
    String getUserName(@WebParam(name = "userId") String userId);
}

实现类UserServiceImpl:

package com.test.cxfdemo.Impl;

import com.test.cxfdemo.dao.User;
import org.springframework.stereotype.Component;

import javax.jws.WebService;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author yanghao
 * @Description:
 * @date 2018/11/6 9:49
 */
@WebService(
        serviceName = "UserService", //对外发布的服务名
        targetNamespace = "http://www.impl.cxfdemo.test.com",
        endpointInterface = "com.test.cxfdemo.Impl.UserService")
@Component
public class UserServiceImpl implements UserService {

    private Map<String, User> userMap = new HashMap<>();

    public UserServiceImpl() {
        System.out.println("向实体类插入数据");
        User user = new User();
        user.setUserId(UUID.randomUUID().toString().replace("-", ""));
        user.setUserName("test1");
        user.setEmail("maplefix@163.xom");
        userMap.put(user.getUserId(), user);
    }

    @Override
    public String getUserName(String userId) {
        return "userId为:" + userId;
    }

    @Override
    public User getUser(String userId) {
        System.out.println("userMap is " + userMap);
        return userMap.get(userId);
    }
}

CXF发布方式:

package com.test.cxfdemo.CxfConfig;

import com.test.cxfdemo.Impl.UserService;
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 javax.xml.ws.Endpoint;

/**
 * @author yanghao
 * @Description:
 * @date 2018/11/6 9:58
 */
@Configuration
public class CxfConfig {

    @Autowired
    private Bus bus;

    @Autowired
    UserService userService;

    @Bean
    public Endpoint endpoint() {
        EndpointImpl endpoint = new EndpointImpl(bus, userService);
        endpoint.publish("/UserService");
        return endpoint;
    }

}

运行即可:

发布成功

网页查看Wsdl:

 

摘抄别人对wsdl的注解,个人觉得还行:

<?xml version="1.0" ?>
<wsdl:definitions name="CodeLanguageService"
    targetNamespace="http://cxf.service.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://cxf.service.com/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <!-- tns 类型的描述 -->
    <wsdl:types>
        <xs:schema elementFormDefault="unqualified" targetNamespace="http://cxf.service.com/"
            version="1.0" xmlns:tns="http://cxf.service.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
            <xs:element name="getCodeRank" type="tns:getCodeRank"></xs:element>
            <xs:element name="getCodeRankResponse" type="tns:getCodeRankResponse"></xs:element>
            <xs:complexType name="getCodeRank">
                <xs:sequence>
                    <xs:element name="codeRank" type="xs:int"></xs:element>
                </xs:sequence>
            </xs:complexType>
            <xs:complexType name="getCodeRankResponse">
                <xs:sequence>
                    <xs:element minOccurs="0" name="codeName" type="xs:string"></xs:element>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>
    </wsdl:types>


    <!-- 描述参数及其类型 -->
    <wsdl:message name="getCodeRankResponse">
        <wsdl:part element="tns:getCodeRankResponse" name="parameters">
        </wsdl:part>
    </wsdl:message>

    <wsdl:message name="getCodeRank">
        <wsdl:part element="tns:getCodeRank" name="parameters">
        </wsdl:part>
    </wsdl:message>

    <!-- 暴露出去的方法的描述,以及对应的描述类型 tns-->
    <wsdl:portType name="CodeLanguage">
        <wsdl:operation name="getCodeRank">
            <wsdl:input message="tns:getCodeRank" name="getCodeRank">
            </wsdl:input>
            <wsdl:output message="tns:getCodeRankResponse" name="getCodeRankResponse">
            </wsdl:output>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:binding name="CodeLanguageServiceSoapBinding" type="tns:CodeLanguage">
        <soap:binding style="document"
            transport="http://schemas.xmlsoap.org/soap/http"></soap:binding>

        <!-- 暴露出去的方法soap格式的描述 -->
        <wsdl:operation name="getCodeRank">
            <soap:operation soapAction="" style="document"></soap:operation>

            <!-- 方法的WSDL参数描述 -->            
            <wsdl:input name="getCodeRank">
                <soap:body use="literal"></soap:body>
            </wsdl:input>

            <!-- 方法的WSDL返回值描述 -->           
            <wsdl:output name="getCodeRankResponse">
                <soap:body use="literal"></soap:body>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>

    <!-- 暴露出去的服务类的描述 -->
    <wsdl:service name="CodeLanguageService">
        <wsdl:port binding="tns:CodeLanguageServiceSoapBinding"
            name="CodeLanguagePort">
            <soap:address location="http://127.0.0.1:6969/ws/CodeLanguageService"></soap:address>
        </wsdl:port>
    </wsdl:service>

</wsdl:definitions>

内容类似。

4、客户端调用代码:

package com.test.cxfdemo.Test;

import com.test.cxfdemo.Impl.UserService;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

/**
 * @author yanghao
 * @Description:
 * @date 2018/11/6 11:33
 */
public class CxfClient {
    public static void main(String[] args) {
        CxfClient.main1();
    }

    /**
     * 1.代理类工厂的方式,需要拿到对方的接口地址
     */
    public static void main1() {
        try {
            // 接口地址
            String address = "http://127.0.0.1:8182/services/UserService?wsdl";
            // 代理工厂
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            // 设置代理地址
            jaxWsProxyFactoryBean.setAddress(address);
            // 设置接口类型
            jaxWsProxyFactoryBean.setServiceClass(UserService.class);
            // 创建一个代理接口实现
            UserService us = (UserService) jaxWsProxyFactoryBean.create();
            // 数据准备
            String userId = "123456";
            // 调用代理接口的方法调用并返回结果
            String result = us.getUserName(userId);
            System.out.println("返回结果:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 2:动态调用
     */
    public static void main2() {
        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://127.0.0.1:8182/services/UserService?wsdl");
        // 需要密码的情况需要加上用户名和密码
        // client.getOutInterceptors().add(new ClientLoginInterceptor(USER_NAME, PASS_WORD));
        Object[] objects = new Object[0];
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            objects = client.invoke("getUserName", "123456");
            System.out.println("返回数据:" + objects[0]);
        } catch (java.lang.Exception e) {
            e.printStackTrace();
        }
    }

}

提供了两种方式,一个是代理模式,还有一个是动态调用。但是在公司项目使用中,这两个方法并不实用!

最好通过生成代码方式:

 

5、CXF自动生成客户端调用代码:

CXF 项目的主页地址是:

http://cxf.apache.org/

下载地址是:

http://cxf.apache.org/download.html

可以下载 解压版也可以下载安装版的。 具体的下载页面如下:

这里下载解压版就可以了。

下载镜像地址:  http://mirror.bit.edu.cn/apache/cxf/3.0.1/apache-cxf-3.0.1.zip

将下载的文件拷贝到响应的文件目录下或者将CXF配置到classPath中:

 

到对应bin目录下或者在对应工程src下,输入:

 

这样在工程目录下就会自动生成客户端调用代码:

 

6、最后给一个客户端生成代码的小例子(非一个工程,但是调用方式一样)


public class CPClientTest {

    public static void main(String[] args) throws MalformedURLException {
        ChargePointService_Service fartory = new ChargePointService_Service(new URL("file:/C:/Users/DELL/Desktop/***********.wsdl"));
        ChargePointService chargePointService = fartory.getChargePointServiceSoap12();

        Client client = ClientProxy.getClient(chargePointService);
        List<Interceptor<? extends Message>> outInterceptors = client.getOutInterceptors();
        List<Interceptor<? extends Message>> inInterceptors = client.getInInterceptors();

        // 客户端的日志出拦截器
        outInterceptors.add(new LoggingOutInterceptor());
        inInterceptors.add(new LoggingInInterceptor());

        String chargeBoxIdentity = "chargedot_0";
        RemoteStopTransactionRequest remoteStopTransactionRequest = new RemoteStopTransactionRequest();
        remoteStopTransactionRequest.setTransactionId(12345678);
        RemoteStopTransactionResponse remoteStopTransactionResponse = chargePointService.remoteStopTransaction(remoteStopTransactionRequest, chargeBoxIdentity);
        System.out.println(remoteStopTransactionResponse.getStatus().value());

    }

}

今天的学习记录就到这儿。

最后记录一个CXF的apche官网解释:http://cxf.apache.org/docs/springboot.html#SpringBoot-AutoConfiguration

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值