5Web Service-整合CXF

Posted MrChengs

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5Web Service-整合CXF相关的知识,希望对你有一定的参考价值。

 

 1、工程准备

 继续使用之前的服务端:https://www.cnblogs.com/Mrchengs/p/10562458.html

 

2、jar准备

 前去apache官网下载响应的jar:http://cxf.apache.org/download.html

 

3、在原来的工程中导入jar文件

 

其中提供的jar相对比较多可以根据开发需求去导入相应的jar!

 

启动服务:

可以看到使用的是jetty服务的

 

4、查看wsdl

 http://localhost:8081/webserviceserver/helloService?wsdl

<wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://impl.service.cr.com/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns2="http://schemas.xmlsoap.org/soap/http" xmlns:ns1="http://service.cr.com/" name="HelloServiceImplService" targetNamespace="http://impl.service.cr.com/">
<wsdl:import location="http://localhost:8081/webserviceserver/helloService?wsdl=HelloService.wsdl" namespace="http://service.cr.com/"> </wsdl:import>
<wsdl:binding name="HelloServiceImplServiceSoapBinding" type="ns1:HelloService">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="sayHello">
<soap:operation soapAction="" style="document"/>
<wsdl:input name="sayHello">
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output name="sayHelloResponse">
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloServiceImplService">
<wsdl:port binding="tns:HelloServiceImplServiceSoapBinding" name="HelloServiceImplPort">
<soap:address location="http://localhost:8081/webserviceserver/helloService"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

 

 创建新的工程,将其拷贝到新的wsdl文件中进行编译

 

进行编译使用

环境变量的配置:https://www.cnblogs.com/ChrisMurphy/p/5224160.html

执行命令:

 

工程目录

 

 

 新建测试类:

 

5、测试类

package cn.com.client;
import com.cr.service.HelloService;
import com.cr.service.impl.HelloServiceImplService;

public class client {
     public static void main(String[] args){
        HelloServiceImplService factory = new HelloServiceImplService();
        HelloService hello = factory.getHelloServiceImplPort();
       String res = hello.sayHello("mr");
        System.out.println(res);
    }
}

 

 

得到的结果如下:

 

6、分析请求和响应 

 

 request

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:q0="http://service.cr.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <q0:sayHello> <arg0>br</arg0> </q0:sayHello> </soapenv:Body> </soapenv:Envelope>

 

 response

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <ns2:sayHelloResponse xmlns:ns2="http://service.cr.com/">
      <return>hello:br</return>
    </ns2:sayHelloResponse>
  </soap:Body>
</soap:Envelope>

 分析:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" 
    xmlns:wsp="http://www.w3.org/ns/ws-policy"
    xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" 
    xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
    xmlns:tns="http://impl.service.cr.com/" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    targetNamespace="http://impl.service.cr.com/" 
    name="HelloServiceImplService">
    
    <!-- 
        types 
        schema : 定义了一些标签结构
     -->
    <types>
        <xsd:schema>
        <xsd:import namespace="http://impl.service.cr.com/" 
            schemaLocation="http://localhost:8081/webserviceserver/helloService?xsd=1"></xsd:import>
        </xsd:schema>
    </types>


    <!-- 
        message: 用来定义消息的结构   soap消息
        part : 指定引用types中定义的标签片断
     -->
    <message name="sayHello">
        <part name="parameters" element="tns:sayHello"></part>
    </message>
    <message name="sayHelloResponse">
        <part name="parameters" element="tns:sayHelloResponse"></part>
    </message>
    
    
    
     <!-- 
        portType: 用来定义服务器端的SEI
        operation : 用来指定SEI中的处理请求的方法
        input : 指定客户端应用传过来的数据, 会引用上面的定义的<message>
        output : 指定服务器端返回给客户端的数据, 会引用上面的定义的<message>
     -->
    <portType name="HelloServiceImpl">
        <operation name="sayHello">
            <input wsam:Action="http://impl.service.cr.com/HelloServiceImpl/sayHelloRequest" message="tns:sayHello"></input>
            <output wsam:Action="http://impl.service.cr.com/HelloServiceImpl/sayHelloResponse" message="tns:sayHelloResponse"></output>
        </operation>
    </portType>
    
    
    <!-- 
        binding : 用于定义SEI的实现类
        type属性: 引用上面的<portType>
        <soap:binding style="document"> : 绑定的数据是一个document(xml)
        operation : 用来定义实现的方法
        <soap:operation style="document" /> 传输的是document(xml)
        input: 指定客户端应用传过来的数据
        <soap:body use="literal" /> : 文本数据
        output : 指定服务器端返回给客户端的数据
        <soap:body use="literal" /> : 文本数据
     -->
    <binding name="HelloServiceImplPortBinding" type="tns:HelloServiceImpl">
        <soap:binding transport="http://schemas.xmlsoap.org/soap/http" 
                    style="document"></soap:binding>
        <operation name="sayHello">
            <soap:operation soapAction=""></soap:operation>
            <input>
                <soap:body use="literal"></soap:body>
            </input>
            <output>
                <soap:body use="literal"></soap:body>
            </output>
        </operation>
    </binding>
    
    <!-- 
        service : 一个webservice的容器
        name属性: 它用一指定客户端容器类
        port : 用来指定一个服务器端处理请求的入口(就SEI的实现)
        binding属性: 引用上面定义的<binding>
        address : 当前webservice的请求地址
     -->
    <service name="HelloServiceImplService">
    <port name="HelloServiceImplPort" binding="tns:HelloServiceImplPortBinding">
    <soap:address location="http://localhost:8082/webserviceserver/helloService"></soap:address>
    </port>
    </service>
</definitions>

 

同时可以参考地址:https://www.cnblogs.com/yangh965/p/5046841.html

 

 

图解:

 

 

7、CXF支持的数据类型

1、基本数据类型:int、float、boolean等

2、引用类型

  -String

  -集合:数组、List、Set、Map

  -自定义类型

 

1、工程目录

 

此时仅仅添加了3个类:DateTypeWs.java  DateTypeWsImpl.java Student.java

 

2、类

Student.java

package com.cr.bean;

public class Student {
    private String name;
    private int price;
        //.....   
 }

 

DateTypeWs.java 
package com.cr.service;

import java.util.List;
import java.util.Map;
import javax.jws.WebMethod;
import javax.jws.WebService;
import com.cr.bean.Student;

@WebService
public interface DateTypeWs {
    
    @WebMethod
    public boolean addStudent(Student stu);
    @WebMethod
    public Student gatStuByPrice(int price);
    @WebMethod
    public List<Student> getStudentByprice(int price);
    @WebMethod
    public Map<Integer, Student> getAllStu();
}

 

DateTypeWsImpl.java 

package com.cr.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jws.WebService;

import com.cr.bean.Student;
import com.cr.service.DateTypeWs;

@WebService
public class DateTypeWsImpl implements DateTypeWs {

    @Override
    public boolean addStudent(Student stu) {
        // TODO Auto-generated method stub
        System.out.println("addStudent:" + stu);
        return true;
    }

    @Override
    public Student gatStuByPrice(int price) {
        System.out.println("gatStuByPrice:" + price);
        return new Student("Mr",1000);
    }

    @Override
    public List<Student> getStudentByprice(int price) {
        System.out.println("getStudentByprice:" + price);
        List<Student> list = new ArrayList<Student>();
        Student s1 = new Student("Mr1",1000);
        Student s2= new Student("Mr2",1000);
        list.add(s2);
        list.add(s1);
        return list;
    }

    @Override
    public Map<Integer, Student> getAllStu() {
        System.out.println("getAllStu:");
        Map<Integer, Student> map = new HashMap<Integer, Student>();
        map.put(11, new Student("Mr11",1000));
        map.put(22, new Student("Mr22",1000));
        return map;
    }

}

 

 启动服务:

package com.cr.server;
import javax.xml.ws.Endpoint;
import com.cr.service.impl.DateTypeWsImpl;
import com.cr.service.impl.HelloServiceImpl;
//发布service
public class server {
    
      public static void main(String[] args){
        String address = "http://localhost:8081/webserviceserver/helloService";
        Endpoint.publish(address , new HelloServiceImpl());
        String address1 ="http://localhost:8081/webserviceserver/dateTypeWs" ;
        Endpoint.publish(address1  , new DateTypeWsImpl());
        System.out.println("发布成功....");
    }
}

 

两个wsdl文件:

 3、测试端:

 将保存为:

 cmd:

 最终得到:

 

4、测试类:

package cn.com.client;

import java.util.List;

import service1.DateTypeWs;
import service1.DateTypeWsImplService;
import service1.Student;

public class client2 {
     public static void main(String[] args){
        
         DateTypeWsImplService factory = new DateTypeWsImplService();
         DateTypeWs ws = factory.getDateTypeWsImplPort();
         
         Student stu = new Student();
         stu.setName("mr");
         stu.setPrice(100);
         boolean sadd = ws.addStudent(stu);
         System.out.println("addStudent(stu):" + sadd);
         
         Student stu1 =  ws.gatStuByPrice(1000);
         System.out.println(stu1);
         
         List<Student>  list = ws.getStudentByprice(1000);
         System.out.println(list);
         
         System.out.println(ws.getAllStu());
    
    }
}

客户端的打印:

 

 服务端的打印

 

 

 此时可以看出关于CXF支持的数据类型

 这里只做了简单的测试

 其中Map的使用会有点问题(JDK不支持)

 

8、一次请求Web Service请求的流程

 一次请求web Service请求的本质:

(1)、浏览器向服务器发送一个soap消息(http请求+xml片段)

(2)、服务器端处理晚请求之后,向客户端返回一个soap消息

 流程:

 

以上是关于5Web Service-整合CXF的主要内容,如果未能解决你的问题,请参考以下文章

web service014——spring整合jaxws发布和调用CXF类型的webservice服务,拷贝服务端接口文件方式

SpringBoot Spring Cloud 整合cxf开发webService接口服务端-流程步骤

Spring整合CXF之发布WebService服务

如何用java调用cxf webservice接口

webservice的cxf和spring整合发布

cxf 整合 spring 时 java.lang.VerifyError异常