使用CXF框架,发布webservice服务,并使用客户端远程访问webservice
  1. CXF介绍 :soa的框架
    * cxf 是 Celtrix (ESB框架)和 XFire(webserivice) 合并而成,并且捐给了apache  
    * CxF的核心是org.apache.cxf.Bus(总线),类似于Spring的 ApplicationContext
    * CXF默认是依赖于Spring的
    * Apache CXF 发行包中的jar,如果全部放到lib中,需要 JDK1.6 及以上,否则会报JAX-WS版本不一致的问题
    * CXF 内置了Jetty服务器 ,它是servlet容器,好比tomcat
  2.CXF特点
    1. 与Spring、Servlet做了无缝对接,cxf框架里面集成了Servlet容器Jetty
    2. 支持注解的方式来发布webservice
    3. 能够显示一个webservice的服务列表
    4. 能够添加拦截器:输入拦截器、输出拦截器 :
         输入日志信息拦截器、输出日志拦截器、用户权限认证的拦截器

CXF框架概念介绍

   通过cxf框架发布webservice
       1. ServerFactoryBean
         - 不设置注解也可以发布webservice服务, 不支持注解
         - 不支持拦截器的添加
       2. JaxWsServerFactoryBean
        - 支持注解
        - 可以添加拦截器
       3. webservice 访问流程:
         1. 检测本地代理描述的wsdl是否与服务端的wsdl一致 ,俗称为握手
         2. 通过soap协议实现通信 ,采用的是post请求 , 数据封装在满足soap规约的xml中
         3. 返回数据 同样采用的是soap通信,  数据封装在满足soap规约的xml中

  Apache CXF 是一个开源的 Services 框架,CXF 帮助您来构建和开发 Services 这些 Services 可以支持多种协议,比如:SOAP、POST/HTTP、RESTful HTTP CXF 大大简化了 Service可以天然地和 Spring 进行无缝集成

 0.jar包:

 

1.ServerFactoryBean来发布web服务

服务类代码如下:(注解无效)

接口:

package cn.it.ws.cxf.a;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
@WebService(serviceName="languageManager")
public interface LanguageService {
    public String getLanguage(int position);

}

 

实现类及发布:

package cn.it.ws.cxf.a;

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

/**开发语言排行描述服务
 * 
 * 
 */
public class LanguageServiceImpl implements LanguageService {
    /* (non-Javadoc)
     * @see cn.it.ws.cxf.a.LanguageService#getLanguage(int)
     */
    @Override
    public String getLanguage(int position){
        String language=null;
        switch (position) {
        case 1:
            language="java"; 
            break;
        case 2:
            language="C";
            break;
        case 3:
            language="Objective-C";
            break;  
        case 4:
            language="C#";
            break;

        default:
            break;
        }
        return language;
    }
    /**通过cxf框架发布webservice
     *  1. ServerFactoryBean
     *    - 不设置注解也可以发布webservice服务, 不支持注解
     *    - 不支持拦截器的添加
     *  2. JaxWsServerFactoryBean
     *    - 支持注解
     *    - 可以添加拦截器
     *  3. webservice 访问流程:
     *    1. 检测本地代理描述的wsdl是否与服务端的wsdl一致 ,俗称为握手
     *    2. 通过soap协议实现通信 ,采用的是post请求 , 数据封装在满足soap规约的xml中
     *    3. 返回数据 同样采用的是soap通信,  数据封装在满足soap规约的xml中
     * @param args*/
    
    public static void main(String[] args) {
        LanguageService languageService=new LanguageServiceImpl();
        ServerFactoryBean bean=new ServerFactoryBean();
        //Endpoint :地址  , 实现对象
        bean.setAddress("http://127.0.0.1:9999/ws/cxf/languangeService");
        bean.setServiceClass(LanguageService.class);//对外提供webservcie的业务类或者接口
        bean.setServiceBean(languageService);//服务的实现bean
        bean.create();//创建,发布webservice
        System.out.println("wsdl地址:http://127.0.0.1:9999/ws/cxf/languangeService?WSDL");
    }
     

}

 

测试:

ServerFactoryBean注意事项:

这种方式没有添加webService注解,也就是说没有注解也可以发布webService服务,但是这种方式不是很规范,比如我们不可以通过注解的方式来修改WSDL的标签信息,

 

2.JaxWsServerFactoryBean来发布web服务

  1. JaxWsServerFactoryBean是ServerFactoryBean的子类,也是功能扩展类。
  2. 此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不出错,但也不会对外暴露任何方法。使用此类生成的wsdl文件更加规范
  3. 更重要的是可以通过添加拦截器拦截请求.

接口:

package cn.it.ws.cxf.a;

import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService(serviceName="languageManager")
public interface LanguageService {
    public @WebResult(name="language")String getLanguage(@WebParam(name="position")int position);

}

 

实现类及发布:

package cn.it.ws.cxf.a;

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

/**开发语言排行描述服务
 * 
 * 
 */
public class LanguageServiceImpl implements LanguageService {
    /* (non-Javadoc)
     * @see cn.it.ws.cxf.a.LanguageService#getLanguage(int)
     */
    @Override
    public String getLanguage(int position){
        String language=null;
        switch (position) {
        case 1:
            language="java"; 
            break;
        case 2:
            language="C";
            break;
        case 3:
            language="Objective-C";
            break;  
        case 4:
            language="C#";
            break;

        default:
            break;
        }
        return language;
    }
     
    public static void main(String[] args) {
        LanguageService languageService=new LanguageServiceImpl();
        JaxWsServerFactoryBean bean=new JaxWsServerFactoryBean();
        //Endpoint :地址  , 实现对象
        bean.setAddress("http://127.0.0.1:9999/ws/cxf/languangeService");
        bean.setServiceClass(LanguageService.class);//对外提供webservcie的业务类或者接口
        bean.setServiceBean(languageService);//服务的实现bean
        //添加输入拦截器  :输入显示日志信息的拦截器
        bean.getInInterceptors().add(new LoggingInInterceptor());
        //添加输出拦截器  :输出显示日志信息的拦截器
        bean.getOutInterceptors().add(new LoggingOutInterceptor());
        
        bean.create();//创建,发布webservice
        System.out.println("wsdl地址:http://127.0.0.1:9999/ws/cxf/languangeService?WSDL");
    }

}

 

测试:

 

3.生成本地代理以及打包测试:

C:\Users\liqiang\Desktop>wsimport http://127.0.0.1:9999/ws/cxf/languangeService?
WSDL
parsing WSDL...



Generating code...


Compiling code...


C:\Users\liqiang\Desktop>jar -cvf Language.jar ./cn
已添加清单
正在添加: cn/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: cn/it/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: cn/it/ws/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: cn/it/ws/cxf/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: cn/it/ws/cxf/a/(输入 = 0) (输出 = 0)(存储了 0%)
正在添加: cn/it/ws/cxf/a/GetLanguage.class(输入 = 617) (输出 = 376)(压缩了 39%)
正在添加: cn/it/ws/cxf/a/GetLanguageResponse.class(输入 = 692) (输出 = 390)(压缩
了 43%)
正在添加: cn/it/ws/cxf/a/LanguageManager.class(输入 = 2325) (输出 = 1044)(压缩了
 55%)
正在添加: cn/it/ws/cxf/a/LanguageService.class(输入 = 806) (输出 = 439)(压缩了 4
5%)
正在添加: cn/it/ws/cxf/a/ObjectFactory.class(输入 = 1647) (输出 = 673)(压缩了 59
%)
正在添加: cn/it/ws/cxf/a/package-info.class(输入 = 242) (输出 = 198)(压缩了 18%)


C:\Users\liqiang\Desktop>

 

 

测试代码:

import cn.it.ws.cxf.a.LanguageManager;
import cn.it.ws.cxf.a.LanguageService;

public class _Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        LanguageManager lManager = new LanguageManager();
        LanguageService languageServicePort = lManager.getLanguageServicePort();
        String language = languageServicePort.getLanguage(1);
        System.out.println(language);
        
    }

}

 

客户端console:

java

服务端console:(握手,接收请求,发送数据(soap))

九月 22, 2017 12:25:56 下午 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
信息: Inbound Message
----------------------------
ID: 4
Address: http://127.0.0.1:9999/ws/cxf/languangeService?WSDL
Http-Method: GET
Content-Type: 
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Type=[null], Host=[127.0.0.1:9999], User-Agent=[Java/1.7.0_80]}
--------------------------------------
九月 22, 2017 12:25:58 下午 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
信息: Inbound Message
----------------------------
ID: 5
Address: http://127.0.0.1:9999/ws/cxf/languangeService
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[text/xml, multipart/related], connection=[keep-alive], Content-Length=[208], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1:9999], SOAPAction=[""], User-Agent=[JAX-WS RI 2.2.4-b01]}
Payload: <?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getLanguage xmlns:ns2="http://a.cxf.ws.it.cn/"><position>1</position></ns2:getLanguage></S:Body></S:Envelope>
--------------------------------------
九月 22, 2017 12:25:59 下午 org.apache.cxf.interceptor.AbstractLoggingInterceptor log
信息: Outbound Message
---------------------------
ID: 5
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getLanguageResponse xmlns:ns2="http://a.cxf.ws.it.cn/"><language>java</language></ns2:getLanguageResponse></soap:Body></soap:Envelope>
--------------------------------------

 

【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】