zoukankan      html  css  js  c++  java
  • Cxf + Spring3.0 入门开发WebService

    转自原文地址:http://sunny.blog.51cto.com/182601/625540/

    由于公司业务需求, 需要使用WebService技术对外提供服务,以前没有做过类似的项目,在网上搜寻了很多资料,最终决定使用Cxf + Spring的框架,原因很简单,就是因为Cxf功能强大并且可以和Spring无缝集成。

            Apache CXF 是一个开放源代码框架,提供了用于方便地构建和开发 Web 服务的可靠基础架构。它允许创建高性能和可扩展的服务,您可以将这样的服务部署在 Tomcat 和基于 Spring 的轻量级容器中,以及部署在更高级的服务器上,例如 Jboss、IBM® WebSphere® 或 BEA WebLogic。

            首先说明一下项目中使用的jar包如下图,服务器端项目项目名称 CxfSpringServer, 客户端项目名称为 CxfSpringClient 两个项目使用的都是以下的jar包, 程序中没有使用最新的cxf-2.4.1版本因为, 该版本不知道是否有问题, 启动的时候总是报错。Spring使用的是3.0。

    第一部分开发服务器端: 

     1: 开发接口程序,接口中定义了serviceName的名称,以及命名空间,注意这个命名空间就是将来客户端中生成的接口的package的路径。

             另外@WebResult(name="out") 这句话定义了wadl文件中输出数据的名字,cxf中默认的输出名称是

    return,当时要改这个名字也花了不少时间。需要改动这个名称的朋友请注意这个细节。

        package com.cxf.bo; 
        import javax.jws.WebParam; 
        import javax.jws.WebResult; 
        import javax.jws.WebService; 
        @WebService(serviceName="IWsTestBO",targetNamespace="http://impl.ws.com") 
        public interface IWsTestBO { 
            @WebResult(name="out") 
            public String execute(@WebParam(name = "arg0",targetNamespace="http://impl.ws.com")String arg0); 
        } 

       2:  接下来开发IWsTestBO 接口的实现类。

     @Service("wsServiceBO")  采用的是spring3.0的注解开发。

        package com.cxf.bo.impl; 
        import javax.jws.WebService; 
        import org.springframework.stereotype.Service; 
        import com.cxf.bo.IWsTestBO; 
        @Service("wsServiceBO") 
        @WebService(targetNamespace="http://impl.ws.com") 
        public class WsTestBOImpl implements IWsTestBO{ 
            public String execute(String arg0) { 
                return "欢迎 " + arg0 + ",调用WebService服务...."; 
            } 
        } 

    3: Spring的配置文件 bo-context.xml。配置文件中定义了WebService的相关属性,注意配置文件中的命名空间的定义是必不可少的。jaxws:endpointbiaoq标签定义了提供Web服务的 Bean 访问地址。 并且配置了服务器接受数据的日志配置,当服务器接受到访问数据时jaxws:features标签配置可以将最原始的日志打印到控制台上。

        <?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:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:context="http://www.springframework.org/schema/context" 
        xmlns:jaxws="http://cxf.apache.org/jaxws" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
                            http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                            http://cxf.apache.org/jaxws  
                            http://cxf.apache.org/schemas/jaxws.xsd">  
         
            <context:component-scan base-package="com.cxf.bo"/> 
             
            <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="wsServiceBean" implementor="#wsServiceBO" address="/execute" publish="true" > 
                <jaxws:features>  
                    <bean class="org.apache.cxf.feature.LoggingFeature" />  
                </jaxws:features>  
            </jaxws:endpoint>  
        </beans> 

     4:接下来是web.xml文件的配置:

        <?xml version="1.0" encoding="UTF-8"?> 
        <web-app version="2.5"  
            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"> 
            <context-param> 
                <param-name>contextConfigLocation</param-name> 
                <param-value>/WEB-INF/bo-context.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>  
                  <load-on-startup>0</load-on-startup>  
              </servlet>  
              <servlet-mapping> 
                <servlet-name>CXFServlet</servlet-name> 
                <url-pattern>/services/*</url-pattern> 
              </servlet-mapping> 
        </web-app> 

    5: 到现在为止服务器端的程序已经开发完成,是不是很简单。现在可以部署到Tomcat6.0服务器。在部署服务器的时候还有一个需要注意的问题。部署tomcat没有问题,但是部署到resin服务器的时候就会报异常: property "javax.xml.stream.supportDTD" not supported 。上网查询了一些资料,发现的确是resin服务器有问题, 改进方案是, 首先在resin.conf配置中找到如下代码:

        <!-- Uncomment to use Resin's XML implementations 
         - <system-property javax.xml.parsers.DocumentBuilderFactory 
             -                 ="com.caucho.xml.parsers.XmlDocumentBuilderFactory"/> 
         - <system-property javax.xml.parsers.SAXParserFactory 
             -                 ="com.caucho.xml.parsers.XmlSAXParserFactory"/> 
        --> 

         如果已经使用,就替换下面,如果没有使用,就加上下面的配置 

    <system-property javax.xml.stream.XMLInputFactory="com.sun.xml.internal.stream.XMLInputFactoryImpl" /> 

         部署之后访问如下地址  http://localhost:9113/CxfSpringServer/services/execute?wsdl  我电脑用的是9113的端口,你的肯定和我的是不一样的,所以你访问的时候改一下端口就可以了。地址访问成功时候会出现一个xml的配置文件的信息,这 里就不展示了。

    第二部分开发客户端:

    1: 客户端和服务器端是两个独立的应用,jar包用的是同一组。如果你用myeclipse的话可以通过myeclipse自带的webservice客户端 生成向导生成客户端接口。根据地址生成客户端这样比较方便,但是生成的文件中除了接口类之外,其它都没什么用的,可以删掉。

     2: 客户端接口类如下

        package com.ws.impl; 
        import javax.jws.WebMethod; 
        import javax.jws.WebParam; 
        import javax.jws.WebResult; 
        import javax.jws.WebService; 
        import javax.xml.ws.RequestWrapper; 
        import javax.xml.ws.ResponseWrapper; 
        @WebService(name = "IWsTestBO", targetNamespace = "http://impl.ws.com") 
        public interface IWsTestBO { 
            @WebMethod 
            @WebResult(name = "out", targetNamespace = "") 
            @RequestWrapper(localName = "execute", targetNamespace = "http://impl.ws.com", className = "com.ws.impl.Execute") 
            @ResponseWrapper(localName = "executeResponse", targetNamespace = "http://impl.ws.com", className = "com.ws.impl.ExecuteResponse") 
            public String execute(@WebParam(name = "arg0", targetNamespace = "http://impl.ws.com") String arg0); 
        } 

    3: 客户端的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:xsd="http://www.w3.org/2001/XMLSchema" 
        xmlns:context="http://www.springframework.org/schema/context" 
        xmlns:jaxws="http://cxf.apache.org/jaxws" 
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
                            http://www.springframework.org/schema/context 
                            http://www.springframework.org/schema/context/spring-context-3.0.xsd 
                            http://cxf.apache.org/jaxws  
                            http://cxf.apache.org/schemas/jaxws.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"/> 
             
            <bean id="wsClient" class="com.ws.impl.IWsTestBO" factory-bean="clientFactory" factory-method="create"/> 
            <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean"> 
                <property name="serviceClass" value="com.ws.impl.IWsTestBO"/> 
                <property name="address" value="http://localhost:9113/CxfSpringServer/services/execute?wsdl"/> 
            </bean> 
        </beans> 

     4:  客户端主函数测试类如下: 

        package com.test; 
        import org.springframework.context.ApplicationContext; 
        import org.springframework.context.support.ClassPathXmlApplicationContext; 
        import com.ws.impl.IWsTestBO; 
         
        public class WsTestClient { 
            public static void main(String[] args) { 
                ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"bo-context.xml"}); 
                IWsTestBO client = (IWsTestBO)ctx.getBean("wsClient"); 
                String result = client.execute("张健"); 
                System.out.println(result); 
            } 
        } 

    5:服务器端输入输出日志如下: 

        信息: Inbound Message 
        ---------------------------- 
        ID: 1 
        Address: /CxfSpringServer/services/execute 
        Encoding: UTF-8 
        Content-Type: text/xml; charset=UTF-8 
        Headers: {cache-control=[no-cache], content-type=[text/xml; charset=UTF-8], connection=[keep-alive], host=[localhost:9113], Content-Length=[213], SOAPAction=[""], user-agent=[Apache CXF 2.2.12], Content-Type=[text/xml; charset=UTF-8], Accept=[*/*], pragma=[no-cache]} 
        Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:execute xmlns:ns1="http://impl.ws.com"><arg0 xmlns="http://impl.ws.com">张健</arg0></ns1:execute></soap:Body></soap:Envelope> 
        -------------------------------------- 
        2011-7-29 12:59:07 org.apache.cxf.interceptor.LoggingOutInterceptor$LoggingCallback onClose 
        信息: Outbound Message 
        --------------------------- 
        ID: 1 
        Encoding: UTF-8 
        Content-Type: text/xml 
        Headers: {} 
        Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:executeResponse xmlns:ns1="http://impl.ws.com"><out>欢迎 张健,调用WebService服务....</out></ns1:executeResponse></soap:Body></soap:Envelope> 
        -------------------------------------- 

         关于Cxf  + Spring3.0 集成开发WebService服务的入门例子程序就写到这里,有问题的童鞋可以留言。我们一起讨论, 谢谢!

  • 相关阅读:
    undefined vs. null
    Callback()
    python基础----元类metaclass
    python基础----__next__和__iter__实现迭代器协议
    python基础----析构函数__del__
    python基础----__slots__方法、__call__方法
    python基础----实现上下文管理协议__enter__和__exit__
    python基础----__setitem__,__getitem,__delitem__
    python基础----isinstance(obj,cls)和issubclass(sub,super)、反射、__setattr__,__delattr__,__getattr__、二次加工标准类型(包装)
    python基础----特性(property)、静态方法(staticmethod)、类方法(classmethod)、__str__的用法
  • 原文地址:https://www.cnblogs.com/longshiyVip/p/4970814.html
Copyright © 2011-2022 走看看