zoukankan      html  css  js  c++  java
  • CXF(webservice服务)私人学习笔记

    俗话说“好记性不如烂笔头”,编程的海洋如此的浩大,养成做笔记的习惯是成功的一步!


    此笔记主要是CXF2.4.2版本的笔记,并且笔记都是博主自己一字一字编写和记录,有错误的地方欢迎大家指正。




    1、说明:
    <1.1>CXF的功能是提供了用于方便地构建和开发 Web 服务的可靠基础架构,使Web Service开发的简单框架。
    <1.2>所需要导入的jar包:CXF的核心jar包是cxf-2.4.2.jar,但所依赖的jar包非常多,需要把lib下的所有58个jar包全部导入。
    <1.3>当CXF与Spring框架整合时,还需要额外的导入Spring的jar包。
    <1.4>如果不是绑定tomcat服务器来运行,只是使用普通的方法运行时,CXF会调用自带的jetty服务器进行启用来提供服务,
    反之,会直接使用tomcat来提供web Service服务。
    <1.5>使用CXF也还需要用到注解@WebService,表示此类事SebService服务类,@WebMethod(exclude=true)表示某个方法不给远程共享。但本地可以调用。
    <1.6>所谓本地,指在统一进程中运行,如同一个项目中调用。
    而远程,是指在不同进程间,如Tomcat6.0访问Tomcat7.0的资源,因为Tom6与Tom7不是两个Tom各自运行,故是属于远程调用。
    <1.7>对外提供的方法必须是public的,且不能使static 和 final类型的。

    <1.8>使用WebService时,如果是不同的语言间相互调用,参数可以是java的集合(List/Set/Map),但是返回参数不能是java的集合(List/Set/Map),否则客户端无法使用,可以手动转换成json格式的字符串。


    <1.9>使用jdk6.0的wsimport的命令解析WebSerice的WSDL后,如果参数是个对象,那么对象的属性不能直接使用基本类型,而是使用JAXBElement对象进行包装:
    JAXBElement<String> str=new JAXBElement<String>(new QName("http://model.ihkmsyf.hfhh.cn","houseName"),String.class,"abc");
    http://model.ihkmsyf.hfhh.cn是通过解析后的WSDL的封装对象里查看到的命名空间,houseName是名称,这两个参数必须一致才能进行传递到服务端。

    2、在普通的java Project中发布web Service的方式(必须要在WebService服务类上加注解@WebService):
    //创建jaxws对象。jaxws:Jaca And Xml Web Service
    JaxWsServerFactoryBean factory=new JaxWsServerFactoryBean();
    //设置地址。访问时必须是http://localhost:8888/say?wsdl,否则会报错
    String address="http://localhost:8888/say";
    factory.setAddress(address);
    //设置服务类
    factory.setServiceBean(new CxfWS());
    //设置访问日志,默认是输出到控制台。
    factory.getInInterceptors().add(new LoggingInInterceptor());
    //设置返回给客户端的信息记录日志,默认是输出到控制台。
    factory.getOutInterceptors().add(new LoggingOutInterceptor());
    //启动CXF内置的jetty服务器。此时将不再使用JDK自带的mini服务器
    factory.create();

    <2.1> 注意,访问时因为http://localhost:8888/say并没有任何数据,因此CXF会报错,只能直接访问WSDL文档:http://localhost:8888/say?wsdl

    3、CXF与Spring框架的整合。
    <3.1>配置spring.xml:
    增加头文件内容:
    xmlns:jaxws="http://cxf.apache.org/jaxws"

    "http://cxf.apache.org/jaxws 
    http://cxf.apache.org/schemas/jaxws.xsd"

    完整的spring.xml配置文件:
    <beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
    http://cxf.apache.org/jaxws 
    http://cxf.apache.org/schemas/jaxws.xsd">

    <!-- 将webservice服务类,注册到springIOC容器中 -->
    <bean id="CxfWSID" class="cn.itcast.cxf.CxfWS"/>

    <!-- 
    将webservice服务类,暴露给远程客户端,以便调用
    与传统的main()方法类似
    目的是:发布webservice服务到指定的URL上

    address:表示发布的URL地址,但这里不需要http://,只要服务名即可
    bean:表示真正提供服务的类
    -->
    <jaxws:server address="/cat">
    <jaxws:serviceBean>
    <ref bean="CxfWSID"/>
    </jaxws:serviceBean>
    </jaxws:server>
     
    <3.2>如果是使用Servlet,因为Servlet并不是有Spring来维护,则无法通过IOC进行注入服务类,则
    需要在Servlet中获取ApplicationContext,直接通过getBeans()来获取WebService的服务类。
    获取方法:
    ApplicationContext ac=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());


    <3.3>如果是使用Struts2,则可以直接使用IOC来注入WebService的服务类。

    <3.4>配置web.xml文件
    <!-- 配置org.apache.cxf.transport.servlet.CXFServlet类
    作用在于:将服务类,转成WSDL描述文件
    注意路径:/myservice/*,值必须访问项目名/myservice,才会得到一个链接WSDL的页面
    -->  
      <servlet>
    <servlet-name>CXF</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
     </servlet>
     
     <servlet-mapping>
    <servlet-name>CXF</servlet-name>
    <url-pattern>/myservice</url-pattern>
     </servlet-mapping>

    <3.5注意事项>
    (1)CXFServlet的<url-pattern>/myservice/*</url-pattern>,是指必须要访问到http:localhost:8080/项目名/myservice,
    才会显示一个链接WSDL的页面。

    (2)address="/cat",表示当通过http:localhost:8080/项目名/myservice显示的链接WSDL的页面地址是
    http:localhost:8080/cat?WSDL。

    (3)如果Web项目也整合了Struts2框架,则必须修改Struts2拦截器的拦截地址,因为struts2的拦截地址是/*,默认拦截所有请求,导致
    原本访问CXFServlet的/myservice也被拦截了,拦截器会找这个路径下的Action,导致最后找不到Action而引起报错。
    解决方式有两种:
    方式1(不建议使用).修改Struts2的拦截地址:
    <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/struts2/*</url-pattern>
     </filter-mapping>

    方式2.自定义一个过滤器Filter,且必须在struts2前声明,判断请求地址如果是/myservice,则转发到CXFServlet。





    4、cxf与Spring的客户端整合方式(在Spring的配置文件xml中增加配置):
    <!-- 配置ws的客户端 -->
    <jaxws:client id="cardImgreconClient"
    <!--提供服务的服务端地址-->
    address="http://10.71.9.10:8080/cxfServerX/ImgReconCard"
    <!--提供服务类的接口,必须与服务端的接口一致-->
    serviceClass="com.wintone.webservice.CardImgrecon"/>




    5、在使用cxf与Spring的客户端整合方式时,要求接口类的包路径必须一样,否则会抛出异常:
    org.apache.cxf.interceptor.Fault: Unexpected wrapper element {****}

     同时,最好保持类名的一致性,还有方法的一致性,以便出现其他错误。
     
     
     
     
    6、凡是提供webservice服务的接口与实现类,都必须在类名或接口名上增加@WebService 的注解,表示是提供ws服务的。
    注意,无论是客户端的接口类还是服务端的接口类,都必须添加该注解。



    7、cxf的服务端与spring整合时,如果想让cxf的部分模块对象也交给spring管理,可以引入相应的cxf的xml配置文件:
    (1)让spring管理 cxf的核心组件、 SOAP binding、servlet transport,则配置:
    <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" />

    (2)让spring管理 cxf的所有模块对象,则配置(不建议用此方式,因为如果没有使用cxf的全部功能,却生成全部模块的对象,浪费资源):
    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath*:META-INF/cxf/cxf-extension-*.xml" />

    或者配置为:

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


    说明:META-INF/cxf/cxf.xml等这些配置文件在cxf.jar包中,只需要导入cxf.jar到项目中,不需要再拷贝对应的文件到自己的项目META-INF下。
     上面的import并不是必须的,如果不引入相应的配置文件,则cxf自己管理模块对象,依旧可以使用cxf提供的ws服务。
     如果项目中有使用spring,建议cxf的核心模块组件对象交由spring统一管理。
     


  • 相关阅读:
    C#中的委托是什么?事件是不是一种委托?
    SQL重点复习
    数据库生成脚本
    用Winfrom动态生成SQL的insert语句
    如何实现远程连接SQL Server 2008 Express
    跨页面传送
    win7 防火墙开启ping
    关于*.class和*.jar的几个基本认识
    使用cobertura确定测试代码的覆盖率
    Java学习笔记之I/O
  • 原文地址:https://www.cnblogs.com/catgwj/p/7503305.html
Copyright © 2011-2022 走看看