WebService之CXF篇

1. CXF相关的jar包可以去http://cxf.apache.org官方网站进行下载。

2. CXF用到的jar分别为:

    

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3. 跟spring集成cxf

   a. 创建一个针对cxf使用的applicationContext.xml文件,比如:appContext_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" 

  xmlns:cxf="http://cxf.apache.org/core"

  xsi:schemaLocation="http://www.springframework.org/schema/beans 

    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

    http://cxf.apache.org/jaxws 

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

    http://cxf.apache.org/core 

    http://cxf.apache.org/schemas/core.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" />

  <!-- 通过Spring创建数据绑定的类

    <bean id="aegisBean" class="org.apache.cxf.aegis.databinding.AegisDatabinding" />

 

    <bean id="jaxWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">

        <property name="wrapped" value="true" />

        <property name="dataBinding" ref="aegisBean" />

    </bean>-->

 

  <!-- jax-ws endpoint定义  -->

  <jaxws:endpoint address="/bulletinQuery">

    <jaxws:implementor ref="bulletinQueryWebService"  />

  </jaxws:endpoint>

 

  <!-- WebService的实现Bean定义 -->

  <bean id="bulletinQueryWebService" class="com.sinosoft.gb.ws.services.IWSBulletinQueryServiceImpl">

    <property name="bulletinMapper">

      <ref bean="bulletinMapper"/>

    </property>

  </bean>

</beans>

注:红色字体部分一定要注意必须引入和注明;蓝色部分为WebService访问时的地址;绿色部分为实现类中相关bean的调用。

b. web.xml中的配置:

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/applicationContext.xml</param-value>

  </context-param>

<listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <!-- Spring 刷新Introspector防止内存泄露 -->  

    <listener>  

        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  

    </listener>  

<!-- CXF 配置   -->

    <servlet>  

        <servlet-name>CXFServlet</servlet-name>  

        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

        <load-on-startup>2</load-on-startup>

    </servlet>  

    <servlet-mapping>  

        <servlet-name>CXFServlet</servlet-name>  

        <url-pattern>/cxfService/*</url-pattern>  

    </servlet-mapping>

 

c. spring配置文件

   将WebService配置使用的applicationContext.xml文件引入:

   <import resource="classpath:com/sinosoft/gb/ws/services/configs/appContext_*.xml"/><!-- 数据接口WebService的spring文件 -->

    注:红色部分以实际路径为准。

4. 服务端代码的编写:

   

package com.sinosoft.gb.ws.services;

 

import java.io.Serializable;

 

import javax.jws.WebParam;

import javax.jws.WebService;

/************************************************************

 * TODO: 简报信息查询接口

 * @author LiuLiang

 * @since 2012-04-25

 ************************************************************/

@WebService( name="bulletinQueryService",targetNamespace="http://www.sinosoft.com.cn/" )

public interface IWSBulletinQueryService extends Serializable

{

  public String getBulletinInfo( @WebParam( name="strXMLInfo" ) String strXMLInfo );

}

 

package com.sinosoft.gb.ws.services;

 

import javax.jws.WebMethod;

import javax.jws.WebService;

 

import org.apache.log4j.Logger;

 

import com.sinosoft.gb.bulletin.mappers.IBulletinMapper;

import com.sinosoft.gb.bulletin.pojo.CBulletinBean;

 

/************************************************************

 * TODO: 简报信息查询接口

 * @author LiuLiang

 * @since 2012-04-25

 ************************************************************/

@SuppressWarnings( "serial" )

@WebService( name="bulletinQueryService",

       serviceName="bulletinQueryService",

       portName="bulletinQueryServicePort",

       targetNamespace="http://www.sinosoft.com.cn/",

       endpointInterface="com.sinosoft.gb.ws.services.IWSBulletinQueryService")

public class IWSBulletinQueryServiceImpl implements IWSBulletinQueryService

{

  private static Logger mobjLogger = Logger.getLogger( IWSBulletinQueryServiceImpl.class.getName() );

  private IBulletinMapper bulletinMapper ;

  @WebMethod( operationName="getBulletinInfo" )

  public String getBulletinInfo(String strXMLInfo)

  {

    mobjLogger.info( "IWSBulletinQueryServiceImpl_getBulletinInfo(...)_通过WebService查询简报相关信息" );

    CBulletinBean objBull = this.getBulletinMapper().getBulletinById( 1719 );

    System.out.println( "webservice==="+objBull.getObjName() );

    return objBull.getObjName();

  }

  public IBulletinMapper getBulletinMapper()

  {

    return bulletinMapper;

  }

  public void setBulletinMapper(IBulletinMapper bulletinMapper)

  {

    this.bulletinMapper = bulletinMapper;

  }

 

}

注意:红色字体部分为需要注意的地方,相关配置请参阅官方详细说明。

5. 至此CXF与Spring的集成就结束了,运行项目后访问会看到: 

 

6. 项目中如果有struts2,还需要作如下修改:

    a. 将struts2(web.xml)的filter修改成自定义的filter:

      

<!-- 定义Struts2的FilterDispathcer的Filter -->

    <filter>

        <filter-name>struts2</filter-name>

        <!-- <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>  -->

        <filter-class>com.sinosoft.gb.filters.CStrutsCustomFilter</filter-class>

        <init-param>

           <param-name>excludeURI</param-name>

           <param-value>cxfService</param-value>

      </init-param>

    </filter>

  <!-- FilterDispatcher用来初始化struts2并且处理所有的WEB请求。 -->

  <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

   b. 类为:

      

package com.sinosoft.gb.filters;

 

import java.io.IOException;

 

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

 

import org.apache.log4j.Logger;

import org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter;

 /**

    * FilterDispatcher 在struts2新的版本中不再支持,建议使用StrutsPrepareAndExecuteFilter

    *

    */

/**

 * TODO: 自定义Struts2的过滤

 * @author LiuLiang

 *

 */

@SuppressWarnings("deprecation") 

public class CStrutsCustomFilter extends StrutsPrepareAndExecuteFilter

{

  private static Logger mobjLogger = Logger.getLogger( CStrutsCustomFilter.class.getName() );

  private static String strExcludeURI = "";

  public CStrutsCustomFilter()

  {

    super();

  }

 

  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,

      ServletException

  {

    HttpServletRequest request = (HttpServletRequest) req;

    String URI = request.getRequestURI();

    int nRet = URI.indexOf( strExcludeURI );

    if ( nRet > 0 )

    {

      chain.doFilter( req, res );

    }

    else

    {

      super.doFilter( req, res, chain );

    }

  }

  public void init(FilterConfig config) throws ServletException

  {

    mobjLogger.info( "CStrutsCustomFilter_获取Filter初始化值..." );

    super.init( config );

    strExcludeURI = config.getInitParameter( "excludeURI" );

  }

}

 7. 测试访问CXF-WebService

    1. 再server端访问配置如下:

      a. 填写client端的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"

  xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">          

 

  <bean id="client" class="com.sinosoft.ws.server.service.IHello" 

      factory-bean="clientFactory" factory-method="create"/>

 

  <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">

    <property name="serviceClass" value="com.sinosoft.ws.server.service.IHello"/>

    <property name="address" value="http://192.168.90.12:7005/ws/hello"/>

  </bean>

</beans>

        b. 测试类为:

          

package com.sinosoft.ws.client.service;

 

import javax.xml.namespace.QName;

import javax.xml.ws.Service;

import javax.xml.ws.soap.SOAPBinding;

 

import com.sinosoft.ws.server.service.IHello;

 

public class HelloClient {

  // 两个参数分别是 web service的targetNamespace和name

  // 默认就是(http://+包名的倒装)和(类名),可以在@WebService()注解中设置

  // 最后有/的话不能忘了,一个字符也不能差

  private static final QName SERVICE_NAME = new QName("http://www.sinosoft.com.cn", "helloworld");

  // 这个是targetNamespace和name+"Port"

  private static final QName PORT_NAME = new QName("http://www.sinosoft.com.cn", "helloworldPort");

 

  private HelloClient() {

  }

 

  public static void main(String args[]) throws Exception {

    Service service = Service.create(SERVICE_NAME);

    // Endpoint Address

    // 这个只要前面对,后面多上一堆也可以,很是奇怪

    // 这样也行??http://localhost:9080/cxf-security/ws/hellosllooiehfkdjfajs

    String endpointAddress = "http://192.168.90.12:7005/ws/hello";

 

    // Add a port to the Service

    service.addPort(PORT_NAME, SOAPBinding.SOAP11HTTP_BINDING, endpointAddress);

 

    IHello helloService = service.getPort(IHello.class);

 

    System.out.println(helloService.sayHello("World"));

  }

}

2. 单独测试的client

    a. 使用cxf包中自带的wsdl2java工具进行生成。将webservice的wsdl文件保存到本地,并命名为:xxx.wsdl或xxx.xml都可以;然后将保存的文件放到cxf包中的bin目录下;打开命令窗口并转到cxf-home/bin目录下,敲如下命令:

      wsdl2java -clicent xxx.wsdl/xxx.xml

      执行完毕后,会在目录下生成相应的目录及类。

   b. 新建一个web项目并将cxf使用的相关jar加入进来,然后将命令生成的相关文件拷贝到项目的src下,一般需要修改的文件为:*****_Service.java 将错误注释掉即可。然后通过******_Client.java进行访问即可。

 

补充:由于CXF总是在更新完善,如果你的项目使用的spring版本比较低的话,亦可以集成最新的CXF,把相关的lib放到项目中的lib目录中,按照上面所述配置完成后如果出现异常,首先检查是否是配置路径问题,其次是否是包冲突造成的。

包冲突造成的异常:

1.could not instantiate bean class [org.apache.cxf.bus.spring.SpringBus]: Constructor threw exception; nested exception is org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl

  解决办法:这个错误的发生是因为与neethi.jar不兼容的版本。 CXF2.7.3以上期待neethi3.x.jar的。我在classpath中有neethi2.x.jar,所以去掉以前的就可以。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值