WebService学习系列之CXF开发WebService

WebService学习系列之CXF开发WebService

手动编写服务端代码开发分为四步:
1.引入cxf相关jar包
2.新增服务接口
3.新增服务接口实现
4.新增发布服务类

手动编写客户端代码开发分为两步:
1.获取wsdl文件
2.新增客户端调用类
调用方式分为两种,分别是静态调用和动态调用

服务端客户端全自动生成代码

  • 通过wsdl文件生成服务端代码和客户端代码的工程中不需要引入任何cxf的jar包(真强大,axis2框架生成的代码还需要引入axis2的jar包)

手动编码服务端开发

1.引入cxf相关jar

 
        
        
            org.apache.cxf
            cxf-rt-frontend-jaxws
            3.1.9
        
        
            org.apache.cxf
            cxf-rt-transports-http-jetty
            3.1.9
        
        
            org.apache.cxf
            cxf-core
            3.1.9
        
    

2.新增服务接口

在接口上添加注解@WebService(serviceName="MyHelloWorldService")

package com.tg.cxf;
/**
 * 

description:

* * @author tanggao * @date 2019/10/22 21:56 * @version 1.0 */ import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; /** * * ......................我佛慈悲...................... * _oo0oo_ * o8888888o * 88" . "88 * (| -_- |) * 0\ = /0 * ___/`---'\___ * .' \\| |// '. * / \\||| : |||// \ * / _||||| -卍-|||||- \ * | | \\\ - /// | | * | \_| ''\---/'' |_/ | * \ .-\__ '-' ___/-. / * ___'. .' /--.--\ `. .'___ * ."" '< `.___\_<|>_/___.' >' "". * | | : `- \`.;`\ _ /`;.`/ - ` : | | * \ \ `_. \_ __\ /__ _/ .-` / / * =====`-.____`.___ \_____/___.-`___.-'===== * `=---=' * ..................................................... ...... 一切有为法,如梦幻泡影,如露亦如电,应作如是观 ........ ......... 三界唯心,万法唯识 ........... ............ bug即空,空即bug,永无bug ............. ..................................................... */ @WebService(serviceName="MyHelloWorldService") public interface HelloWorldService { public @WebResult(name="returnHello")String sayHello(@WebParam(name="name")String name); public @WebResult(name="returnPerson")Person getPerson(@WebParam(name="name")String name); }

3.新增服务接口实现

package com.tg.cxf;
/**
 * 

description:

* * @author tanggao * @date 2019/10/22 21:59 * @version 1.0 */ import javax.jws.WebParam; /** * * ......................我佛慈悲...................... * _oo0oo_ * o8888888o * 88" . "88 * (| -_- |) * 0\ = /0 * ___/`---'\___ * .' \\| |// '. * / \\||| : |||// \ * / _||||| -卍-|||||- \ * | | \\\ - /// | | * | \_| ''\---/'' |_/ | * \ .-\__ '-' ___/-. / * ___'. .' /--.--\ `. .'___ * ."" '< `.___\_<|>_/___.' >' "". * | | : `- \`.;`\ _ /`;.`/ - ` : | | * \ \ `_. \_ __\ /__ _/ .-` / / * =====`-.____`.___ \_____/___.-`___.-'===== * `=---=' * ..................................................... ...... 一切有为法,如梦幻泡影,如露亦如电,应作如是观 ........ ......... 三界唯心,万法唯识 ........... ............ bug即空,空即bug,永无bug ............. ..................................................... */ public class HelloWorldServiceImpl implements HelloWorldService { public String sayHello(String name) { return "hello,"+name; } public Person getPerson(String name) { Person p =new Person(); p.setName(name); p.setAge(24); return p; } }

实现类依赖的Person类如下:


4.新增发布服务类

package com.tg.cxf;
/**
 * 

description:

* * @author tanggao * @date 2019/10/22 22:02 * @version 1.0 */ import org.apache.cxf.jaxws.JaxWsServerFactoryBean; /** * * ......................我佛慈悲...................... * _oo0oo_ * o8888888o * 88" . "88 * (| -_- |) * 0\ = /0 * ___/`---'\___ * .' \\| |// '. * / \\||| : |||// \ * / _||||| -卍-|||||- \ * | | \\\ - /// | | * | \_| ''\---/'' |_/ | * \ .-\__ '-' ___/-. / * ___'. .' /--.--\ `. .'___ * ."" '< `.___\_<|>_/___.' >' "". * | | : `- \`.;`\ _ /`;.`/ - ` : | | * \ \ `_. \_ __\ /__ _/ .-` / / * =====`-.____`.___ \_____/___.-`___.-'===== * `=---=' * ..................................................... ...... 一切有为法,如梦幻泡影,如露亦如电,应作如是观 ........ ......... 三界唯心,万法唯识 ........... ............ bug即空,空即bug,永无bug ............. ..................................................... */ public class CxfServer { public static void main(String[] args) { System.out.println("web Service start"); HelloWorldServiceImpl implementor = new HelloWorldServiceImpl(); String address="http://localhost/helloWorld"; JaxWsServerFactoryBean factoryBean = new JaxWsServerFactoryBean(); factoryBean.setAddress(address); //设置暴露地址 factoryBean.setServiceClass(HelloWorldService.class); //接口类 factoryBean.setServiceBean(implementor); //设置实现类 factoryBean.create(); System.out.println("web Service started"); } }

验证服务发布是否成功,访问wsdl,wsdl路径即为发布的路径加上?wsdl

http://localhost/helloWorld?wsdl

客户端开发步骤

1.获取wsdl文件

wsdl文件可以是实时的wsdl网址,比如:

http://localhost/helloWorld?wsdl

也可以是离线的wsdl文件

2.手动编写客户端静态调用代码

package com.tg.cxf;
/**
 * 

description:

* * @author tanggao * @date 2019/10/22 22:05 * @version 1.0 */ import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.jaxws.JaxWsProxyFactoryBean; /** * * ......................我佛慈悲...................... * _oo0oo_ * o8888888o * 88" . "88 * (| -_- |) * 0\ = /0 * ___/`---'\___ * .' \\| |// '. * / \\||| : |||// \ * / _||||| -卍-|||||- \ * | | \\\ - /// | | * | \_| ''\---/'' |_/ | * \ .-\__ '-' ___/-. / * ___'. .' /--.--\ `. .'___ * ."" '< `.___\_<|>_/___.' >' "". * | | : `- \`.;`\ _ /`;.`/ - ` : | | * \ \ `_. \_ __\ /__ _/ .-` / / * =====`-.____`.___ \_____/___.-`___.-'===== * `=---=' * ..................................................... ...... 一切有为法,如梦幻泡影,如露亦如电,应作如是观 ........ ......... 三界唯心,万法唯识 ........... ............ bug即空,空即bug,永无bug ............. ..................................................... 静态调用需要依赖service类,因为客户端调用cxf webservice接口的过程中需要服务器端提供service,很不方便,如果同一个项目中则没有区别。 */ public class StaticClient { public static void main(String[] args) { // 创建WebService客户端代理工厂 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); // 判断是否抛出异常 factory.getOutInterceptors().add(new LoggingInInterceptor()); // 注册webservice接口 factory.setServiceClass(HelloWorldService.class); // 配置webservice地址 factory.setAddress("http://localhost/helloWorld?wsdl"); // 获得接口对象 HelloWorldService service = (HelloWorldService) factory.create(); // 调用接口方法 String result = service.sayHello("aaaaaaaaaa"); System.out.println("调用结果:" + result); } }

运行结果

静态调用需要依赖service类,因为客户端调用cxf webservice接口的过程中需要服务器端提供service,很不方便,如果同一个项目中则没有区别

3.手动编写客户端动态调用代码

package com.tg.cxf;
/**
 * 

description:

* * @author tanggao * @date 2019/10/22 22:08 * @version 1.0 */ import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory; import javax.xml.namespace.QName; public class DynamicClient { public static void main(String[] args) { JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance(); org.apache.cxf.endpoint.Client client = dcf .createClient("http://localhost/helloWorld?wsdl"); // url为调用webService的wsdl地址 // namespace是命名空间,methodName是方法名 QName name = new QName("http://cxf.tg.com/", "sayHello"); String xmlStr = "aaaaaaaa"; // paramvalue为参数值 Object[] objects; try { objects = client.invoke(name, xmlStr); System.out.println(objects[0].toString()); } catch (Exception e) { e.printStackTrace(); } } }

运行结果

一般都不会自己写代码,都是通过工具生成客户端代码

通过工具根据wsdl文件生成客户端调用类

官网下载cxf ,下载完后如下图


image.png

在bin目录中有一个wsdl2java命令


image.png

注意,如果要直接使用该命令,需要将bin加入环境变量中
准备wsdl文件,如下是本地保存的wsdl文件 C:\Users\Administrator\Desktop\daima\helloWorld.xml


  


  

  

  

  

  
    
      
    
  

  
    
      
    
  

  
    
      
    
  

  
    
      
    
  

  
    
      
      
    
  


  
  
    
    
  
  
    
    
  
  
    
    
  
  
    
    
  
  
    
      
    
      
    
    
    
      
    
      
    
    
  
  
    
    
      
      
        
      
      
        
      
    
    
      
      
        
      
      
        
      
    
  
  
    
      
    
  

打开cmd ,输入

wsdl2java -encoding utf-8 -p com.asiainfo.ws.boss -d E:\idea-yaxin\cxfclient\src -client   C:\Users\Administrator\Desktop\daima\helloWorld.xml

参数

-encoding 指定编码集
-p 指定其wsdl的命名空间,也就是要生成代码的包名:
-d 指定要产生代码所在目录
-client 生成客户端测试web service的代码

在指定工程路径下生产了客户端代码


image.png

因为生成代码时指定了参数 -client,所以客户端调用类HelloWorldService_HelloWorldServicePort_Client 也生成了,如下类

package com.cxf.client;

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

import javax.xml.namespace.QName;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * This class was generated by Apache CXF 3.3.3
 * 2019-11-02T18:14:45.976+08:00
 * Generated source version: 3.3.3
 *
 */
public final class HelloWorldService_HelloWorldServicePort_Client {

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

    private HelloWorldService_HelloWorldServicePort_Client() {
    }

    public static void main(String args[]) throws java.lang.Exception {
        URL wsdlURL = MyHelloWorldService.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();
            }
        }

        MyHelloWorldService ss = new MyHelloWorldService(wsdlURL, SERVICE_NAME);
        HelloWorldService port = ss.getHelloWorldServicePort();
        {
        System.out.println("Invoking sayHello...");
        java.lang.String _sayHello_name = "";
        java.lang.String _sayHello__return = port.sayHello(_sayHello_name);
        System.out.println("sayHello.result=" + _sayHello__return);
        }
        {
        System.out.println("Invoking getPerson...");
        java.lang.String _getPerson_name = "";
        com.cxf.client.Person _getPerson__return = port.getPerson(_getPerson_name);
        System.out.println("getPerson.result=" + _getPerson__return);
        }

        System.exit(0);
    }

}

直接修改一下传入的参数,查看运行结果


通过wsdl文件生成服务端代码

还可以通过已经制定好的wsdl文件生成服务端代码,
有两个好处:
1.可以通过制定好的wsdl文件,直接生成服务端代码,无需编码,节省编码时间
2.当我们写客户端时,如果要服务端当前不能调用,而我们又要测试客户端的业务逻辑,所有可以根据wsdl文件生成服务端,服务端直接返回成功结果给客户端调式用。

生成服务端命令

wsdl2java -encoding utf-8 -p com.cxf.server -impl -d E:\idea-yaxin\cxfserver\src -server  C:\Users\Administrator\Desktop\daima\helloWorld.xml

参数

-encoding 代码编码集
-p 指定其wsdl的命名空间,也就是要生成代码的包名:
-d 指定要产生代码所在目录
-server 生成服务器启动web service的代码
-impl 生成web service的服务端代码

在指定工程生成了服务端代码


image.png

因为指定了参数-server ,所以生成了启动类HelloWorldService_HelloWorldServicePort_Server


image.png

修改一下生成类的wsdl文件路径


直接启动HelloWorldService_HelloWorldServicePort_Server类


image.png

查看wsdl文件


到此为止,webservice服务端代码生成成功!
cxf强大之处在于通过wsdl文件生成的客户端和服务端不需要引入任何cxf的jar包!!!!,但是Axis2生成的服务端和客户端确需要引入大量jar包,这就是我不喜欢用它的原因!

你可能感兴趣的:(WebService学习系列之CXF开发WebService)