CXF+S2SH集成

CXF+S2SH服务端集成时,遇到很多问题。

主要是jar不兼容的问题。

CXF 2.6 + Hibernate3+struts2.0+spring3.0 

1、首先看Root项目服务端的配置:

 

Action只是测试调用服务端cxf-springDemo用的

Struts2Filter : 继承FilterDispatcher类,过滤cxfServlet的路径,以免struts2的过滤器将其过滤掉了。

Struts.properties:   struts.action.excludePattern=/webservice/.*

配置struts2的过滤机制,不过滤路径为webservice/.*URL

这个URLCXF占用,等下在web.xml会配置的。

SpringService : 对外提供的接口  注意:在接口类名上要使用注解@WebService,

SpringServiceImpl :实现SpringService接口,对于服务端需要实现里面的方法。

注意:对于实现类要使用DAO层对象操作数据库,需要使用注解注入DAO层对象。如下:

 

//此处要采用注解注入

@Component("SpringService")

@WebService(endpointInterface="com.spring.service.SpringService",targetNamespace=http://service.spring.com/)

public class SpringServiceImpl implements SpringService {

 JeNewsDAO JeNewsDAO ;

@Resource(name="JeNewsDAO")

public void setJeNewsDao(JeNewsDAO JeNewsDAO) {

this.JeNewsDAO = JeNewsDAO;

}

2、 新建applicationContext.xml ,专门配置cxf webservice

<?xml version="1.0" encoding="UTF-8"?> 

 <!-- START SNIPPET: beans --> 

 <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://www.springframework.org/schema/beans 

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

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

    <!—以下三个文件在cxf.jar包中的META-INF下面可以看到 -->

 <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" /> 

 

 <!-- cxf+ssh服务端配置 ,就要写实现类,开启服务端 -->

 <jaxws:endpoint id="springService"

 implementor="com.spring.service.impl.SpringServiceImpl" 

 address="/eshop" />   

  </beans>

3、 web.xml配置:

<context-param>

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

<param-value>classpath:applicationContext*.xml</param-value>

</context-param>

<listener>

<listener-class>

org.springframework.web.context.ContextLoaderListener

</listener-class>

</listener>

 

<!-- 注意:CXFservlet要写在contextLoaderListener后面, struts2 Filter的前面 -->

 

 <servlet> 

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

 <servlet-class> 

 org.apache.cxf.transport.servlet.CXFServlet 

 </servlet-class> 

 <load-on-startup>1</load-on-startup> 

 </servlet> 

 <!-- 需要注意:cxfServletstruts2URL 不能都写/*,需要区分 -->

 <servlet-mapping> 

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

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

 </servlet-mapping>

<filter>   

<filter-name>s2</filter-name>   

    <filter-class>   

      com.spring.filter.Struts2Filter  <!—这个filter是自已写的继承了FilterDispatcher -->

    </filter-class>   

</filter>   

<filter-mapping>   

    <filter-name>s2</filter-name>   

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

</filter-mapping>

OK啦,服务端配好了。

CXF+S2SH客户端的配置如下:

1、服务端项目打包

首先将服务端的com.spring下的类进行打包,客户端在调用服务端接口时需要引入这个jar包:

如果接口的实现类中用到了实体类,则把实体类复制到SpringService接口的同级包下

如下:JeChannel,JeClass,JeNews都是实体类

并在这些实体类上加上@XmlType (namespace="http://service.spring.com/")

以区分MODEL中的实体类,避免报以下错误:

Two classes have the same XML type name,请使用 @XmlType.name 和 @XmlType.namespace 为类分配不同的名称

打包的类有:com.spring包下的和MODEL中引用到的实体类,如:JeChannel,JeClass,JeNews

 

创建一个新项目,配置与上面服务端项目一样,

1、com.spring.action.SpringAction类的代码如下:

package com.spring.action;

import java.util.ArrayList;
import java.util.List;

import com.cxf.service.CXFService;
import com.lxsoft.model.JeChannel.JeChannel;
import com.lxsoft.model.JeClass.JeClass;
import com.lxsoft.model.JeNews.JeNews;
import com.moss.portal.category.Category;
import com.moss.portal.information.Information;
import com.opensymphony.xwork2.ActionSupport;
import com.spring.service.SpringService;

public class SpringServiceAction extends ActionSupport {
 private SpringService client;// 服务1
 private CXFService client2;// 服务2

 private List<Information> newsList; //数据测试
 private List<JeNews> newsList2;// 

//getter setter .... 省略

 

 /**
  * 测试显示服务端1中的信息 注意将服务端的包加载进来
  */
 public String toDemo1() {
  try {
   this.newsList = this.client.findAll();
    } catch (Exception e) {
   System.out.println("获取 信息异常......");
   e.printStackTrace();
  }
  return SUCCESS;
 }

 

 /**
  * 测试显示服务端2 中的所有信息 注意将服务端2的包加载进来
  */
 public String toDemo2() {
  try {
   this.newsList2 = this.client2.findAllNews();
     } catch (Exception e) {
   System.out.println("获取 信息异常......");
   e.printStackTrace();
  }
  return SUCCESS;
 }

 

 /**
  * 将服务端1信息转入到服务端2的数据库
  */
 public String toConvert() {
    try {
     // 1、获取所有服务端1数据库信息
   this.newsList = this.client.getInformations();
             // 2、遍历信息,将信息填充到服务端2数据库
   for (Information f : this.newsList) {
    JeNews jeNews = new JeNews();

       jeNews.setTitle(f.getTitle());

    jeNews.setContent(f.getContent());
          // 保存到服务端2的数据库中
       this.client2.saveNews(jeNews);
   }
     } catch (Exception e) {
   System.out.println("获取 信息异常......");
   e.printStackTrace();
   return INPUT;
  }
  return SUCCESS;
 }

 

}

 

1、修改后的applicationContext.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?> 

 <!-- START SNIPPET: beans --> 

 <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://www.springframework.org/schema/beans 

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

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

    <!—以下三个文件在cxf.jar包中的META-INF下面可以看到 -->

 <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" /> 

<!-- cxf+SSH客户端配置 无需写实现类,开启客户端-->  

    <bean id="client" class="com.spring.service.SpringService" factory-bean="clientFactory" factory-method="create"/>

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

         <property name="serviceClass" value="com.spring.service.SpringService"/>

         <!-- 这里指定服务端地址,在action类中可以调用对应接口类的方法  -->

         <property name="address" value=http://localhost:8080/cxf-spring/webservice/SpringServer></property>

    </bean>

<!-- 可以同时开启多个客户端-->

    <bean id="client2" class="com.spring.service.SpringService" factory-bean="clientFactory2" factory-method="create"/>
    <bean id="clientFactory2" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
         <property name="serviceClass" value="com.spring.service.SpringService"/>
         <!-- 这里指定服务端地址,在action类中可以调用对应接口类的方法-->
         <property name="address" value="http://localhost:8080/demo/webservice/testService"/>
    </bean>

 

   <bean id="SpringAction"  class="com.spring.action.SpringServiceAction" scope="prototype">

      <property name="client" ref="client"/>

     <property name="client2" ref="client2"/>

   </bean>

 

 </beans>

配置struts.xml action,(因为会在action类中调用服务端的接口了)

以下这段配置通常会写在strus.xml文件的最末尾,以免与其它配置加载发生冲突。

<constant name="struts.objectFactory" value="spring" />   

    <constant name="struts.devMode" value="true" />

   <package name="cxf-spring" extends="struts-default">

   <action name="hello" class="SpringAction" method="toDemo1">

      <result>/index.jsp</result>

   </action>          

<action name="hello2" class="SpringAction" method="toDemo2">

      <result>/index2.jsp</result>

   </action>    

<action name="convert" class="SpringAction" method="toConvert">

      <result>/success.jsp</result>

   </action>    

    </package>

 布署服务端和客户端项目,运行

访问地址:http://localhost:8080/hello  可以显示服务端1的信息

http://localhost:8080/hello2    可以显示服务端2的信息

http://localhost:8080/convert   可以将服务端1的信息导入到服务端2的数据库中

 

 

posted @ 2012-11-07 17:26  miss you  阅读(577)  评论(0编辑  收藏  举报