ServerSWebService之CXF_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > ServerSWebService之CXF

ServerSWebService之CXF

 2017/6/12 5:31:56  归宿的微博小窝1984  程序员俱乐部  我要评论(0)
  • 摘要:前言:WebService就目前来讲已经是一种成熟的技术了,目前对WebService支持的框架也很多,虽然本人并没有对各框架做个测试,但分析比较各框架的优缺点(较为主观),最后还是选择了CXF作为样例框架进行分析,主要是因为性能较佳,支持JAX-WS,Spring无缝集成,上手快等特点,本文旨在提供CXF基本入门demo,帮助快速入门了解CXF的使用。本篇文章重点关注以下问题:CXF简介,及对安装的简要说明;CXF发布服务和调用服务的几种方式;客户端调用服务时候的代理超时机制
  • 标签:Server Web Service Webservice

? ? ? ? ?前言:WebService就目前来讲已经是一种成熟的技术了,目前对WebService支持的框架也很多,虽然本人并没有对各框架做个测试,但分析比较各框架的优缺点(较为主观),最后还是选择了CXF作为样例框架进行分析,主要是因为性能较佳,支持JAX-WS,Spring无缝集成,上手快等特点,本文旨在提供CXF基本入门demo,帮助快速入门了解CXF的使用。

本篇文章重点关注以下问题:

  • CXF简介,及对安装的简要说明;
  • CXF发布服务和调用服务的几种方式;
  • 客户端调用服务时候的代理超时机制;
  • CXF对WebService的拦截器支持;
  • CXF整合Spring发布、调用WebService。

1、?CXF简介及安装说明

1.1 ? CXF简介 ?

? ? ?Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF。?

???? Apache CXF 是一个开源的 WebServices 框架,CXF 帮助您利用 Frontend 编程 API 来构建和开发 Services ,像 JAX-WS 。这些 Services 可以支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTP 或者CORBA?,并且可以在多种传输协议上运行,比如:HTTP、JMS 或者 JBI,CXF 大大简化了 Services 的创建,同时它继承了 XFire 传统,一样可以天然地和 Spring 进行无缝集成。

1.2 安装流程

  1. 到官网下载安装包:http://cxf.apache.org/
  2. 将bin目录下的命令添加到环境变量中:CXF_HOME:D:\Program Files\apache-cxf-3.1.11,再将bin追加到path中;
  3. cmd命令行中输入wsdl2java,看是不是已将所有命令添加到环境编程成功。

2、CXF发布、调用服务的几种方式

? ? CXF服务端、、客户端实现WebService服务的方式主要有两点:

  1. ?ServerFactoryBean
  2. JaxWsServiceFactoryBean(建议用此类)

? ? ? ?调用原则如下图:



?2.1 ServerFactoryBean实现服务端和客户端

2.1.1 ServerFactoryBean实现服务端编程

? ? ? ? 首先做两点说明,使用CXF发布一个服务于与Jax-Ws发布一个服务完全不同:

  • 即使不使用@WebService注解,一样可以发布成功某个服务;
  • 即使此类没有对外公布的方法,一样可以发布成功。

? ? ??OK,废话不多说,直接上代码:

? ? ? 先定义对外发布服务的接口

class="java">public interface IHelloService {
    String sayHello(String name);
}
? ? 然后利用ServerFactoryBean对外发布服务:
/**
 * 使用ServerFactoryBean发布CXF的Web服务
 */
public class HelloService implements IHelloService {
    
    /**
     * 对外发布的方法
     * @param name
     * @return
     */
    public String sayHello(String name) {
        System.err.println("hello, " + name);
        return "hello, " + name;
    }

    public static void main(String[] args) {
        ServerFactoryBean bean = new ServerFactoryBean();
        
        // 服务的发布地址
        bean.setAddress("http://localhost:9999/sayHello");
        // 对外提供服务的类的类型,在面向接口编程时填写接口,否则写实现类
        bean.setServiceClass(IHelloService.class);
        // 对外提供服务的功能实现类
        bean.setServiceBean(new HelloService());
        // 发布服务  publish()...
        bean.create();
        System.out.println("服务已发布...");
    }
}
? ? 使用CXF发布完此服务后,使用wsimport生成客户端一样可以成功调用此服务。最后废话一句,CXF要依赖的包太多了,当然也是我懒得去区分各个包的作用导致的。在浏览器中输入http://localhost:9999/sayHello?wsdl验证服务是否发布。?

2.1.2?ServerFactoryBean实现客户端编程

? ? ? 首先获取服务接口,有两种方式,如何可以直接联系服务方拿到定义的接口文件则可以拿过来直接使用,当然也可以利用wsimport获得接口文件来使用(此方法在java RMI一文中有阐述)。这里我就直接把服务端的接口文件直接拿过来用了。

? ? ? 直接上代码:

/**
 * 使用ClientProxyFactoryBean调用CXF的Web服务(必须是使用ServerFactoryBean方式发布的)
 */
public class HelloServiceClient {

    public static void main(String[] args) {
        ClientProxyFactoryBean bean = new ClientProxyFactoryBean();
        
        // 设置客户端需要使用服务的地址
        bean.setAddress("http://localhost:9999/sayHello");
        // 创建服务接口对象(接口对象用的仍是服务端的服务接口对象)
        IHelloService helloService = (IHelloService) bean.create(IHelloService.class);
        // 使用服务
        String result = helloService.sayHello("熊燕子");
        System.out.println(result);
    }
}

? ? 当然,客户端既然用的仍然是CXF,那么还是需要导入那么多包的。哭

2.2?JaxWsServiceFactoryBean实现服务端和客户端

? ? ? ?JaxWsServiceFactoryBean是ServerFactoryBean的子类,也是功能扩展类,此类必须要在被发布为服务的类的上添加@WebService注解,如果不加注解,虽然运行不会报错,但是也不会对外暴露任何方法。最重要的一点是,使用此类生成的wsdl文件更加规范

2.2.1 JaxWsServiceFactoryBean实现服务端

? ? 先定义服务接口,直接上代码:

@WebService
@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)
/**
 * 通过@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)转换为实现SOAP1.2
 */
public interface IHelloService {

	public String sayHello(String name);
}

? ? 然后发布服务?:

/**
 * 使用JaxWsServerFactoryBean发布CXF的Web服务
 * 注意:需要发布的服务接口必须加入WebService注解,如果不加,虽然不报错,但是所有的方法都暴露不出来
 */
public class HelloService implements IHelloService {
    
    /**
     * 对外发布的方法
     * @param name
     * @return
     */
    @Override
    public String sayHello(String name) {
        System.err.println("hello, " + name);
        return "hello, " + name;
    }
    
    public static void main(String[] args) {
        JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();
        
        // 设置服务的发布地址
        bean.setAddress("http://localhost:9999/sayHello");
        // 对外提供服务的类的类型,在面向接口编程时填写接口,否则写实现类
        bean.setServiceClass(IHelloService.class);
        // 对外提供服务的功能实现类
        bean.setServiceBean(new HelloService());
        // 发布服务  publish()...
        bean.create();
        System.out.println("服务已发布...");
    }
}
? ? ? ??使用CXF发布完此服务后,使用wsimport生成客户端一样可以成功调用此服务。与wsimport类似的还有CXF提供的wsdl2java命令,也同样可以生成客户端代码。此工具位于CXF_HOME/bin目录下,只是参数与wsimport有所不同,它包含以下常用参数:
  • -d:指明代码生成的目录;
  • -p:指定生成的新的包结构。
比如对上述发布服务生成客户端代码:wsdl2java -d C:\Users\Administrator\Desktop\temp?http://localhost:9999/sayHello?wsdl,则会生成如下java文件,拷贝到客户度即可使用。在下面会对如何调用进行说明。

?2.2.2?JaxWsServiceFactoryBean实现客户端

? ? ? ?用JaxWsServiceFactoryBean发布的服务,在客户端需要使用JaxWsProxyFactoryBean类进行调用,调用过程与前面的过程类似。

? ? ? ?这里还是直接把服务端的服务接口文件IHelloService.javaz直接拷贝到客户端来使用。(当然,wsimport和wsdl2java都可以用来生成功能接口)

/**
 * 利用JaxWsProxyFactoryBean进行WebService服务调用(只能调用JaxWsServerFactoryBean发布的服务)
 */
public class HelloServiceClient {

    public static void main(String[] args) {
        JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();
        // 设置客户端需要使用服务的地址
        bean.setAddress("http://localhost:9999/sayHello");
        // 设置服务接口的类型
        bean.setServiceClass(IHelloService.class);
        // 创建服务接口对象
        IHelloService helloService = (IHelloService) bean.create();
        // 调用WebService服务
        String ret = helloService.sayHello("aa");
        System.out.println(ret);
    }
}

?2.3 客户端调用方法补充

? ? ? ? 利用wsdl2java命令生成客户端调用代码,进行客户端开发。

/**
 * 通过wsdl2java生成客户端代码调用Webservice服务
 */
public class HelloServiceClient {

    public static void main(String[] args) {
      // 获取服务类对象
      IHelloServiceService helloServiceService = new IHelloServiceService();
      // 获取服务类对象的接口
      IHelloService        helloService        = helloServiceService.getIHelloServicePort();
      // 调用服务
      String               result              = helloService.sayHello("熊燕子");
      System.out.println(result);
    }
}

? ? 可以发现wsdl2java不管是命令还是生成调用客户端代码,都与wsimport非常类似。

  • 大小: 9.2 KB
  • 大小: 15.1 KB
  • 查看图片附件
发表评论
用户名: 匿名