使用cxf构建webservice

简介: 一、简介   cxf是apache下的一个开源的,功能齐全的WebService框架。是由Celtix和XFire两个开源框架组合而成。cxf可以帮助我们使用前端编程模型构建和开发服务,如JAX- WS和JAZ-RS。

一、简介
  cxf是apache下的一个开源的,功能齐全的WebService框架。是由Celtix和XFire两个开源框架组合而成。cxf可以帮助我们使用前端编程模型构建和开发服务,如JAX- WS和JAZ-RS。这些服务可以使用不同的协议,如SOAP,XML/HTTP,RESTFul HTTP或者CORBA和使用各种的数据传输协议,如HTTP,JMS 和JBI。除此之外cxf还有如下特性:

  • 使用简单,可与maven,spring等进行集成。
  • 支持Web Service标准,包括soap,WS-I Basic Profile, WSDL, WS-Addressing, WS-Policy, WS-ReliableMessaging, WS-Security, WS-SecurityPolicy, WS-
  • SecureConverstation, 和WS-Trust (partial)。
  • 对二进制和遗留协议的支持,cxf设计并提供了一个可插拔的架构,不仅支持xml还支持非xml类型的绑定,如json,corba。可使用多种类型格式进行传输。
  • 提供了多中工具生成代码,如WSDL to JAVA, WSDL to JavaScript, Java to JavaScript等。

二、使用

  cxf的下载地址如下:http://cxf.apache.org/download.html 。这里下载的是windows版本apache-cxf-3.0.3.zip。在c盘根目录下解压该文件,解压后文件目录结构如下:

  

其中bin目录下的是为我们提供的相关转换工具,docs目录下的是相关文档,lib目录下是cxf的jar依赖;license目录下的是许可,samples是为我们提供的例子。

  新建一个java项目cxf_server,并将lib下的jar文件(不包括endorse,和integration目录)添加到项目的依赖。

  1、编写MyService接口 代码如下:

1 package com.cxf.testauto;
2 
3 import javax.jws.WebService;
4 
5 @WebService
6 public interface MyService {
7 
8     public String sayHello(String username, String address, String school); 
9 }

  2、编写MyService的实现类

package com.cxf.testauto;

public class MyServiceImpl implements MyService {

    @Override
    public String sayHello(String username, String address, String school) {
        System.out.println("sayHello is invoked!");

        String result = "hello: " + username + ", your info is: " + address + ", " + school;

        return result;
    } 
}

  3、Server 服务的启动类

package com.cxf.testauto;

import org.apache.cxf.interceptor.LoggingInInterceptor;
import org.apache.cxf.interceptor.LoggingOutInterceptor;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;

public class Server {

    public static void main(String[] args) {
        JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
        factory.setAddress("http://localhost:9000/myservice");
        factory.setServiceClass(MyServiceImpl.class);
        factory.getInInterceptors().add(new LoggingInInterceptor());
        factory.getOutInterceptors().add(new LoggingOutInterceptor());
        factory.create();
    }
}

  主要:如果jdk版本比较低会报java.lang.LinkageError: JAXB 2.0 API jar is being loaded, but this RI (...) needs 2.2 API.类似的错误。此时需要在运行该类的时候指定运行参数,打开Run Configurations窗口,在VM arguments输入如下参数:

-Djava.ext.dirs=C:\apache-cxf-3.0.3\lib\endorsed

  表示指定jvm运行的时候,加载C:\apache-cxf-3.0.3\lib\endorsed目录下的jar文件。如下图所示

  

  点击Apply,运行即可。

  4、运行Server类

  启动成功后,我们可以通过浏览器访问wsdl文件,使用http://localhost:9000/myservice?wsdl 地址访问即可。wsdl文件内容如下:

 1 <?xml version='1.0' encoding='UTF-8'?>
 2 <wsdl:definitions xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 3     xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://testauto.cxf.com/"
 4     xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
 5     name="MyServiceImplService" targetNamespace="http://testauto.cxf.com/">
 6     <wsdl:types>
 7         <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
 8             xmlns:tns="http://testauto.cxf.com/" elementFormDefault="unqualified"
 9             targetNamespace="http://testauto.cxf.com/" version="1.0">
10 
11             <xs:element name="sayHello" type="tns:sayHello" />
12             <xs:element name="sayHelloResponse" type="tns:sayHelloResponse" />
13 
14             <xs:complexType name="sayHello">
15                 <xs:sequence>
16                     <xs:element minOccurs="0" name="arg0" type="xs:string" />
17                     <xs:element minOccurs="0" name="arg1" type="xs:string" />
18                     <xs:element minOccurs="0" name="arg2" type="xs:string" />
19                 </xs:sequence>
20             </xs:complexType>
21 
22             <xs:complexType name="sayHelloResponse">
23                 <xs:sequence>
24                     <xs:element minOccurs="0" name="return" type="xs:string" />
25                 </xs:sequence>
26             </xs:complexType>
27 
28         </xs:schema>
29     </wsdl:types>
30     
31     <wsdl:message name="sayHelloResponse">
32         <wsdl:part element="tns:sayHelloResponse" name="parameters">
33         </wsdl:part>
34     </wsdl:message>
35     <wsdl:message name="sayHello">
36         <wsdl:part element="tns:sayHello" name="parameters">
37         </wsdl:part>
38     </wsdl:message>
39     
40     <wsdl:portType name="MyService">
41         <wsdl:operation name="sayHello">
42             <wsdl:input message="tns:sayHello" name="sayHello">
43             </wsdl:input>
44             <wsdl:output message="tns:sayHelloResponse" name="sayHelloResponse">
45             </wsdl:output>
46         </wsdl:operation>
47     </wsdl:portType>
48     
49     <wsdl:binding name="MyServiceImplServiceSoapBinding" type="tns:MyService">
50         <soap:binding style="document"
51             transport="http://schemas.xmlsoap.org/soap/http" />
52         <wsdl:operation name="sayHello">
53             <soap:operation soapAction="" style="document" />
54             <wsdl:input name="sayHello">
55                 <soap:body use="literal" />
56             </wsdl:input>
57             <wsdl:output name="sayHelloResponse">
58                 <soap:body use="literal" />
59             </wsdl:output>
60         </wsdl:operation>
61     </wsdl:binding>
62     
63     <wsdl:service name="MyServiceImplService">
64         <wsdl:port binding="tns:MyServiceImplServiceSoapBinding"
65             name="MyServiceImplPort">
66             <soap:address location="http://localhost:9000/myservice" />
67         </wsdl:port>
68     </wsdl:service>
69 </wsdl:definitions>

  5、通过wsdl文件生成客户端

  将C:\apache-cxf-3.0.3\bin 添加进系统环境变量path中。

  cmd进入c盘根目录,运行命令

C:\>wsdl2java -client -encoding utf8 -frontend jaxws21 http://localhost:9000/myservice?wsdl 

  该命令根据wsdl生产调用的客户端。-client表示生成客户端;-encoding表示生成的java代码的编码格式;frontend表示参照jaxws21标准;ttp://localhost:9000/myservice?wsdl为wsdl的地址,也可以是磁盘上的某一个wsdl文件。

  执行结果如下:

  命令执行成功后将会在c盘根目录下生成客户端的调用代码:生成的代码结构如下

 

  我们主要使用到的就是MyService_MyServiceImplPort_Client.java这个调用类。
  6、进行调用,新建另一个java工程cxf_client,将生成的客户端代码拷贝到这个工程中。并对MyService_MyServiceImplPort_Client.java类进行修改。
  MyService_MyServiceImplPort_Client.java修改后的内容如下:

package com.cxf.testauto;

/**
 * Please modify this class to meet your needs
 * This class is not complete
 */

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.ws.RequestWrapper;
import javax.xml.ws.ResponseWrapper;

/**
 * This class was generated by Apache CXF 3.0.3
 * 2015-01-13T13:58:38.847+08:00
 * Generated source version: 3.0.3
 * 
 */
public final class MyService_MyServiceImplPort_Client {

    private static final QName SERVICE_NAME = new QName("http://testauto.cxf.com/", "MyServiceImplService");

    private MyService_MyServiceImplPort_Client() {
    }

    public static void main(String args[]) throws java.lang.Exception {
        URL wsdlURL = MyServiceImplService.WSDL_LOCATION;
        if (args.length > 0 && args[0] != null && !"".equals(args[0])) { 
            File wsdlFile = new File(args[0]);
            try {
                if (wsdlFile.exists()) {
                    wsdlURL = wsdlFile.toURI().toURL();
                } else {
                    wsdlURL = new URL(args[0]);
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }
      
        MyServiceImplService ss = new MyServiceImplService(wsdlURL, SERVICE_NAME);
        MyService port = ss.getMyServiceImplPort();  
        
        {
        System.out.println("Invoking sayHello...");
        java.lang.String _sayHello_arg0 = "zhangsan";
        java.lang.String _sayHello_arg1 = "beijing";
        java.lang.String _sayHello_arg2 = "hello world";
        java.lang.String _sayHello__return = port.sayHello(_sayHello_arg0, _sayHello_arg1, _sayHello_arg2);//对webservice 接口进行调用
        System.out.println("sayHello.result=" + _sayHello__return);


        }

        System.exit(0);
    }

}

  运行该类,完成调用。

  client端打印的结果如下:


  server端打印的结果如下:

  

目录
相关文章
|
4月前
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
【Azure 应用服务】Web App Service 中的 应用程序配置(Application Setting) 怎么获取key vault中的值
|
1月前
【Azure App Service】PowerShell脚本批量添加IP地址到Web App允许访问IP列表中
Web App取消公网访问后,只允许特定IP能访问Web App。需要写一下段PowerShell脚本,批量添加IP到Web App的允许访问IP列表里!
|
4月前
|
关系型数据库 MySQL Linux
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
【Azure 应用服务】在创建Web App Service的时候,选Linux系统后无法使用Mysql in App
|
4月前
|
Shell PHP Windows
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
【Azure App Service】Web Job 报错 UNC paths are not supported. Defaulting to Windows directory.
|
4月前
|
Linux 应用服务中间件 网络安全
【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
【Azure 应用服务】查看App Service for Linux上部署PHP 7.4 和 8.0时,所使用的WEB服务器是什么?
|
4月前
【Azure 应用服务】通过 Web.config 开启 dotnet 应用的 stdoutLog 日志,查看App Service 产生500错误的原因
【Azure 应用服务】通过 Web.config 开启 dotnet 应用的 stdoutLog 日志,查看App Service 产生500错误的原因
|
4月前
|
Linux Python
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
【Azure 应用服务】Azure App Service For Linux 上实现 Python Flask Web Socket 项目 Http/Https
|
4月前
|
存储 安全 网络安全
【Azure 环境】使用Azure中的App Service部署Web应用,以Windows为主机系统是否可以启动防病毒,防恶意软件服务呢(Microsoft Antimalware)?
【Azure 环境】使用Azure中的App Service部署Web应用,以Windows为主机系统是否可以启动防病毒,防恶意软件服务呢(Microsoft Antimalware)?
|
4月前
|
存储 Linux 网络安全
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
【Azure 应用服务】App Service For Linux 如何在 Web 应用实例上住抓取网络日志
|
4月前
【Azure 云服务】Azure Cloud Service 为 Web Role(IIS Host)增加自定义字段 (把HTTP Request Header中的User-Agent字段增加到IIS输出日志中)
【Azure 云服务】Azure Cloud Service 为 Web Role(IIS Host)增加自定义字段 (把HTTP Request Header中的User-Agent字段增加到IIS输出日志中)