使用 CXF 做 webservice 简单例子

一、对比Axis2和CXF

jws的发布对java webservice框架产生了巨大的影响,经过大浪淘沙,目前java开发webservice的框架主要包括axis2和cxf。

axis2和cxf都是apache旗下的产品,但是其目的不同,导致webservice开发方法也不一样。两个框架都得到了开发者的支持。有必要对二者进行以下对比。

 
  Axis2 CXF
目标 WebService引擎 简易的SOA框架,可以作为ESB
ws* 标准支持 不支持WS-Policy WS-Addressing,WS-Policy, WS-RM, WS-Security,WS-I Basic Profile
数据绑定支持 XMLBeans、JiBX、JaxMe 、JaxBRI、ADB JAXB, Aegis, XMLBeans, SDO, JiBX
spring集成 不支持 支持
应用集成 困难 简单
多语言 支持C/C++ 不支持
部署 web应用 嵌入式
服务监控和管理 支持 不支持

结论:

  1. 如果希望以一种一致的方式实现webservice,特别是有跨语言的需求时,应该使用Axis2
  2. 如果需要在现有的java程序(包括web应用)中增加webservice支持,应该使用CXF


二、编写服务类

从Java6开始,WebService API从Java EE复制到了Java SE。并遵循了一系列的标准,比如JSR181(Web Service 元数据),JSR224(JAX-WS,基于XML的WebService API),JSR67(SAAJ,SOAP附件标准)等。 并分别定义到javax.jws, javax.xml.ws 和 javax.xml.soap包中。

JSR181支持使用标注(annotation)来定义WebService。在javax.jws中主要的标注类包括:

 
标注 说明
WebService 将 Java 类标记为实现 Web Service,或者将 Java 接口标记为定义 Web Service 接口
WebMethod 定制Web Service方法
WebParam 定制Web Service方法的参数
WebResult 定制Web Service方法的返回值
SOAPBinding 指定WebService的SOAP映射样式
使用标注可以在不改变代码逻辑的前提下让外部代码能够获得更多的元数据。下面就用javax.jws定义的标注来声明一个WebService

  • pom增加CXF依赖
      < dependencies >
            < dependency >
                 < groupId > org.apache.cxf groupId >
                 < artifactId > apache-cxf artifactId >
                 < version > ${cxf.version} version >
                 < type > pom type >
            dependency >
      dependencies >
      < properties >
            < cxf.version > 2.2.4 cxf.version >
      properties >
  • 增加接口服务
package com.dogiant.demo;

import javax.jws.WebService;

@WebService
public interface CXFDemo {
      public String sayHello(String foo );
}
  • 实现服务类
package com.dogiant.demo;

import javax.jws.WebService;

@WebService (endpointInterface = "com.dogiant.demo.CXFDemo" , serviceName = "cxfDemo" )
public class CXFDemoImpl implements CXFDemo {

      @Override
      public String sayHello(String foo ) {
            return "hello " + foo ;
     }

}

三、 以endpoint发布

到目前为止,使用的都是标准Java SE中的东西。下面要开始依赖CXF实现一些功能。

首先是服务的发布。CXF不仅支持通过Web容器发布WebService,也可以在嵌入式代码中通过jetty发布WebService。

下面的测试类包含了发布服务和客户端调用的代码:
            < dependency >
                 < groupId > junit groupId >
                 < artifactId > junit artifactId >
                 < version > 4.12 version >
                 < scope > test scope >
            dependency >

package com.dogiant.demo;

import javax.xml.ws.Endpoint;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.junit.Assert;

import junit.framework.TestCase;

public class TestEndpoint extends TestCase {
     
      private static final String ADDRESS = "http://localhost:9000/cxfdemo" ;

      protected void setUp() throws Exception {
            super .setUp();

           System. out .println( "Starting Server" );
           CXFDemoImpl demo = new CXFDemoImpl();

           Endpoint. publish( ADDRESS , demo );
           System. out .println( "Start success" );
     }

      public void testSayHello() {

           JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
            factory .setServiceClass(CXFDemo. class );
            factory .setAddress( ADDRESS );
           CXFDemo client = (CXFDemo) factory .create();
           Assert. assertEquals( client .sayHello( "foo" ), "hello foo" );
     }
}

信息: Creating Service {http://demo.dogiant.com/}CXFDemoImplService from class com.dogiant.demo.CXFDemo
2016-3-28 10:49:48 org.apache.cxf.endpoint.ServerImpl initDestination
信息: Setting the server's publish address to be http://localhost:9000/cxfdemo
2016-3-28 10:49:48 org.mortbay.log.Slf4jLog info
信息: Logging to org.slf4j.impl.JDK14LoggerAdapter(org.mortbay.log) via org.mortbay.log.Slf4jLog
2016-3-28 10:49:48 org.mortbay.log.Slf4jLog info
信息: jetty-6.1.21
2016-3-28 10:49:48 org.mortbay.log.Slf4jLog info
信息: Started [email protected]:9000
Start success
2016-3-28 10:49:48 org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://demo.dogiant.com/}CXFDemoService from class com.dogiant.demo.CXFDemo


四、在webapp中发布
web.xml
xml version = "1.0" encoding = "UTF-8" ?>
< web-app xmlns = "http://java.sun.com/xml/ns/javaee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation = "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd "
      version = "2.5" >

      < display-name > spring- cxf-demo display-name >
     
      < context-param >
            < param-name > contextConfigLocation param-name >
            < param-value > classpath*:spring/spring-config*. xml param-value >
      context-param >
     
      < listener >
           < listener-class > org.springframework.web.context.ContextLoaderListener listener-class >
      listener >
     
      < servlet >
            < servlet-name > CXFServlet servlet-name >
           < servlet-class > org.apache.cxf.transport.servlet.CXFServlet servlet-class >
      servlet >
      < servlet-mapping >
            < servlet-name > CXFServlet servlet-name >
            < url-pattern > /services/* url-pattern >
      servlet-mapping >

web-app >

spring-config-cxf.xml
xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
      xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws = "http://cxf.apache.org/jaxws"
      xsi:schemaLocation = "http://cxf.apache.org/jaxws
     http://cxf.apache.org/schemas/jaxws.xsd
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd" >


      < import resource = "classpath:META-INF/cxf/cxf.xml" />
      < import resource = "classpath:META-INF/cxf/cxf-extension-soap.xml" />
      < import resource = "classpath:META-INF/cxf/cxf-servlet.xml" />

      < jaxws:endpoint id = "cxfDemo" implementor = "com.dogiant.demo.CXFDemoImpl"
            address = "/cxfdemo" />


beans >
http://localhost:8080/services/cxfdemo

            < dependency >
                 < groupId > javax.servlet groupId >
                 < artifactId > servlet-api artifactId >
                 < version > 2.5 version >
                 <scope >provided scope >   //此处不注意会报错
            dependency >

http://localhost:8080/services/cxfdemo?wsdl

五、客户端
package com.dogiant.demo;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

public class CXFClient {
      public static void main(String[] args ) {
      JaxWsProxyFactoryBean proxy = new JaxWsProxyFactoryBean();
            proxy .setServiceClass(CXFDemo. class );
            proxy .setAddress( "http://localhost:8080/services/cxfdemo" );
           CXFDemo cxf = (CXFDemo) proxy .create();
           System. out .println( cxf .sayHello( "haha" ));
     }
}

与spring集成

xml version = "1.0" encoding = "UTF-8" ?>
< beans xmlns = "http://www.springframework.org/schema/beans"
      xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws = "http://cxf.apache.org/jaxws"
      xsi:schemaLocation = "http://cxf.apache.org/jaxws
     http://cxf.apache.org/schemas/jaxws.xsd
     http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans.xsd" >

      < bean id = "clientFactory" class = " or g.apache.cxf.jaxws.JaxWsProxyFactoryBean" >
            < property name = "serviceClass" value = "com.dogiant.demo.CXFDemo" />
            < property name = "address" value = "http://localhost:8080/services/cxfdemo" />
      bean >

      < bean id = "client" class = "com.dogiant.demo.CXFDemo" factory-bean = "clientFactory"
            factory-method = "create" />

beans >

测试用例

package com.dogiant.demo;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith (SpringJUnit4ClassRunner. class )
@ContextConfiguration (locations = { "classpath:spring/spring-config-cxf-client.xml" })
public class TestCXFClient {
     
      @Autowired
      private CXFDemo client ;
     
      @Test
      public void test() {
           System. out .println( client .sayHello( "hello" ));
     }

}


附:


cxf官网 
February 8, 2016 - Apache CXF 3.1.5/3.0.8 released!
http://cxf.apache.org/index.html


cxf-demo例子

https://github.com/dogiant/cxf-demo 













cxf官网 
February 8, 2016 - Apache CXF 3.1.5/3.0.8 released!
http://cxf.apache.org/index.html

你可能感兴趣的:(java)