`

cxf和spring mvc的集成

阅读更多
Spring MVC是通过DispatcherServlet来加载Spring配置文件的,因此不需要在web.xml中配置ContextLoaderListener。但是CXF却需要通过ContextLoaderListener来加载Spring。

这样就产生了一个矛盾,如果不配置ContextLoaderListener,CXF就无法正常使用。但如果配置ContextLoaderListener,又会造成Spring的重复加载(DispatcherServlet一次,ContextLoaderListener一次)

在网上查了一下资料,只看到一个国外的程序员提出不配置ContextLoaderListener,通过写一个CXFController,来替代默认的CXFServlet。但是这种HACK的方式总是不太好

所以我采用一种折中的方式,来解决Spring MVC和cxf并存的问题。但是也不是很优雅,希望有人能给出更好的办法

首先是web.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="MyFramework" version="3.0">
	
	<display-name>MyFramework</display-name>
	
	<context-param>
    	<param-name>contextConfigLocation</param-name>
        <param-value> 
        	WEB-INF/beans.xml, 
            WEB-INF/cxf.xml
        </param-value> 
   	</context-param>
	
    <listener>  
        <listener-class>  
            org.springframework.web.context.ContextLoaderListener  
        </listener-class>  
    </listener>  
	
	<servlet>
		<servlet-name>framework</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>  
        	<param-name>contextConfigLocation</param-name>  
        	<param-value>WEB-INF/spring-mvc.xml</param-value>  
   		</init-param>  
   		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>framework</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
	
	<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>/webservice/*</url-pattern>  
    </servlet-mapping>  
	
</web-app>

在ContextLoaderListener里面,加载cxf和spring的公共配置信息。然后在DispatcherServlet中加载spring mvc所需的信息。利用Spring配置文件拆分的方式,既实现spring mvc和cxf的共存,又避免spring配置信息的重复加载

然后是公共的配置信息,beans.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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       						http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       						http://www.springframework.org/schema/context 
      			 			http://www.springframework.org/schema/context/spring-context-3.1.xsd
      			 			http://www.springframework.org/schema/tx
      		 				http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">

	<context:component-scan base-package="com.huawei.framework" />

	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:jdbc.properties</value>
			</list>
		</property>
	</bean>

	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="driverClass" value="${jdbc.driver}" />
		<property name="jdbcUrl" value="${jdbc.url}" />
		<property name="user" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="minPoolSize" value="10" />
		<property name="maxPoolSize" value="50" />
	</bean>

	<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="mappingLocations"
			value="classpath:/com/huawei/framework/model/**/*.hbm.xml" />
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.jdbc.fetch_size">50</prop>
				<prop key="hibernate.jdbc.batch_size">25</prop>
				<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
			</props>
		</property>
	</bean>

	<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
		<property name="sessionFactory" ref="sessionFactory" />
		<property name="fetchSize" value="10" />
	</bean>

	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
	</bean>

	<tx:annotation-driven transaction-manager="transactionManager" />

</beans>

然后是cxf所需的信息,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://www.springframework.org/schema/beans
       						http://www.springframework.org/schema/beans/spring-beans-3.1.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-servlet.xml" />

	<jaxws:endpoint id="helloWorld"
		implementorClass="com.huawei.framework.webservice.HelloWorldImpl"
		address="/HelloWorld" />

</beans>

最后是spring mvc所需的信息,spring-mvc.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:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	xsi:schemaLocation="http://www.springframework.org/schema/beans
       						http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       						http://www.springframework.org/schema/context 
      			 			http://www.springframework.org/schema/context/spring-context-3.1.xsd
      			 			http://www.springframework.org/schema/mvc
        					http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

	<context:component-scan base-package="com.huawei.framework" />

	<mvc:annotation-driven />

	<mvc:default-servlet-handler />

	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		p:prefix="/WEB-INF/view/" p:suffix=".jsp"
		p:viewClass="org.springframework.web.servlet.view.JstlView" />

</beans>

这顺便还带来一个附带的好处,即进行单元测试的时候,可以仅加载必须的类,比如做DAO组件的单元测试,就不需要加载spring-mvc.xml和cxf.xml了
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:WebContent/WEB-INF/beans.xml" })
public class UserDaoHibernateTest {

	@Autowired
	private UserDao dao;

	private static String ID;

	@Test
	public void testInsert() {
		User user = new User();
		user.setName("fme001");
		user.setAge(23);
		dao.insert(user);
	}

	@Test
	public void testQueryByName() {
		String name = "fme001";
		User user = dao.queryByName(name);
		assertEquals(23, user.getAge());
		ID = user.getId();
	}

	@Test
	public void testQueryByAge() {
		int age = 23;
		List<User> result = dao.queryByAge(age);
		assertEquals(1, result.size());
	}

	@Test
	public void testQueryAll() {
		List<User> result = dao.queryAll();
		assertEquals(1, result.size());
	}

	@Test
	public void testQuery() {
		User user = dao.query(ID);
		assertEquals(23, user.getAge());
		assertEquals("fme001", user.getName());
	}

	@Test
	public void testUpdate() {
		User user = dao.query(ID);
		user.setAge(24);
		dao.update(user);
		user = dao.query(ID);
		assertEquals(24, user.getAge());
	}

	@Test
	public void testDelete() {
		User user = dao.query(ID);
		dao.delete(user);
	}

}

可以看到,集成cxf和spring mvc确实不算很方便,需要绕一绕。上述方法只是一个折中的方案,希望新版本的cxf可以提供一个CXFController,这样的话就可以统一用DispatcherServlet来加载Spring,不配置ContextLoaderListener。这样的话web.xml可以简洁很多。或者如果哪位网友有更好的方式,请指教一下
分享到:
评论
4 楼 admin_si 2015-10-22  
这位大侠 按照你这样配置还是不行
3 楼 kyfxbl 2013-12-11  
白小神 写道
可以继承CXFservlet 实现自己的servletControl
比较疑惑的是 spring MVC支持restFul 风格的 webService
为什么还要集成CXF 实现webService?


你说的web service是值restful风格的http接口吗?那么确实不需要cxf

cxf是专门处理“狭义”的web service,并不是泛指一般的web服务。利用cxf可以完成一些特定的任务,比如根据wsdl反向生成代码,处理soap协议等。spring mvc不做这个
2 楼 白小神 2013-12-11  
可以继承CXFservlet 实现自己的servletControl
比较疑惑的是 spring MVC支持restFul 风格的 webService
为什么还要集成CXF 实现webService?
1 楼 ccor 2012-07-19  
这是正解,spring的容器本身支持分层,ContextLoaderListener加载的是最底层的(父容器),而DispatcherServlet作为web服务层是继承了父容器中的bean,并且底层容器中的对象无法访问上层子容器中的对象。

ps.结婚了,当爹了,还是要继续钻研技术:) 同道啊~

相关推荐

    SPRING-MVC-MQ-CXF-REST_Demo

    "SPRING-MVC-MQ-CXF-REST_Demo"这个项目很可能是用来演示如何在同一个应用中整合Spring MVC、MQ、CXF和REST技术。项目可能包含了以下部分: 1. Spring MVC配置:展示了如何设置DispatcherServlet、视图解析器以及...

    cxf+spring+client

    在这个"**cxf+spring+client**"的主题中,我们将深入探讨CXF与Spring框架结合创建客户端服务的细节,以及如何利用Spring MVC来增强应用程序的交互性。 首先,让我们关注CXF。CXF允许开发者使用Java编程语言来定义和...

    apache-cxf集成spring基本包

    集成Apache CXF和Spring的优势在于,它能够充分利用两者的优点:CXF的Web服务支持和Spring的容器管理,使得开发者能够更加专注于业务逻辑,而不是基础设施。同时,这种集成也方便了服务的测试、监控和扩展,提高了...

    Spring MVC、CXF、Web Service

    Spring MVC、CXF和Web Service是企业级Java应用开发中的三个关键组件,它们分别在不同的层面上服务于构建高效、可扩展的Web应用程序。 Spring MVC,全称Spring Model View Controller,是Spring框架的一部分,专为...

    CXF2.1.3+spring3.0+struts2.3.4

    【标题】"CXF2.1.3+spring3.0+struts2.3.4" 描述了集成这三大框架实现Web服务的场景。CXF是一个开源的服务框架,它允许开发人员创建和消费各种Web服务。Spring是Java企业级应用的核心框架,提供了依赖注入和面向切面...

    CXF整合Spring需要用到的JAR包

    CXF不仅支持SOAP和RESTful API,还提供了与Spring框架的深度集成,使得服务的创建、配置和管理更加便捷。本文将详细探讨在整合CXF和Spring时所需的JAR包以及它们在系统中的作用。 首先,我们需要理解CXF和Spring...

    CXF Spring Web Service 程序

    Spring还有一套丰富的模块,如Spring MVC用于构建Web应用程序,Spring JDBC和Spring JPA用于数据库操作,以及Spring Integration用于企业集成。 ### 3. CXF与Spring的整合 CXF与Spring的整合主要体现在以下几个...

    springMVC整合cxf所需的jar包

    总之,Spring MVC和CXF的整合涉及到多个层次的技术,从Web服务的创建、配置到集成到Spring的MVC框架中,每个环节都需要细心处理。正确的jar包配置是成功整合的关键,只有确保所有必要的依赖都已引入,才能使得Web...

    cxf集成springmvc所需jar

    将CXF与Spring MVC集成可以充分利用两者的优势,实现更灵活、可扩展的服务层和控制层。下面我们将详细讨论如何进行这种集成以及所需的关键jar文件。 首先,让我们了解CXF。CXF允许开发者通过SOAP或RESTful方式创建...

    cxf+spring

    【标题】"cxf+spring" 是一个基于Apache CXF框架和Spring框架的集成应用,用于构建服务端的Web服务。Apache CXF是一个开源的Java框架,主要用于创建、部署和管理WS-*(Web Services)标准栈的服务。它支持SOAP、...

    CXF与Spring整合下载文件四

    标题中的"CXF与Spring整合下载文件四"表明这是一个关于整合Apache CXF(一个开源的Java框架,用于构建和开发服务导向架构(SOA)应用程序)和Spring框架的教程或资源集合。Spring是一个广泛使用的Java应用框架,它...

    CXFJAXWS-Client:JAXWS客户端,使用Apache CXF和Spring MVC

    此外,CXF还支持SOAP、RESTful、JSON等不同通信协议,并与Spring框架紧密集成,简化了配置和依赖注入。 接下来,我们来看Spring MVC。Spring是一个广泛使用的Java企业级应用框架,特别适合构建Web应用程序。Spring ...

    maven整合Spring MVC Mybatis(包括mybatis反向生产代码*适合新手,高手请自动忽略)

    【标题】"maven整合Spring MVC Mybatis"涉及的核心知识点主要集中在Java Web开发中的三大框架——Spring、Spring MVC和Mybatis的集成应用上。对于初学者来说,理解这些框架的协同工作方式至关重要。 首先,Maven是...

    CXF+Spring官方实例学习

    在CXF和Spring的集成项目中,良好的日志记录可以帮助开发者追踪问题,理解程序运行状态,优化性能。你需要了解如何配置log4j来满足项目的需求,例如定义不同的日志级别(DEBUG, INFO, WARN, ERROR等)和输出目的地...

    apache-cxf-3.1.14.zip和springmvc 配置jar

    在与Spring MVC集成时,CXF可以作为Spring应用中的一个组件,提供更强大的Web服务功能。 标题中提到的"apache-cxf-3.1.14.zip"是Apache CXF 3.1.14版本的源码或二进制发行包。这个压缩包通常包含了CXF的核心库、...

    cxf-spring 服务端and客户端

    【标题】"cxf-spring 服务端and客户端"揭示了这个项目是关于Apache CXF框架与Spring框架的集成,用于构建服务端和客户端应用程序。Apache CXF是一个开源的Java框架,它允许开发者创建和消费Web服务,而Spring框架则...

    CXF+Spring发布webservice服务的例子

    总的来说,CXF与Spring的集成使得Web服务的发布变得更加简单和直观。通过上述步骤,你可以快速地创建一个基于CXF和Spring的SOAP服务,为其他系统提供API接口。这个例子不仅适用于学习,也适合在实际项目中应用。

    CXF RESTful spring maven CRUD

    2. **Spring集成**:Spring框架可以与CXF结合使用,提供依赖注入和AOP支持,简化服务的创建和管理。例如,可以使用Spring的`@WebService`和`@Path`注解来声明和配置RESTful服务。 3. **HashMap模拟数据库**:在没有...

    webservice CXF结合Spring所需jar包

    本篇文章将深入探讨如何使用CXF与Spring集成,以及在开发过程中所需的jar包。 首先,让我们理解Web服务的基本概念。Web服务是一种通过网络(通常基于HTTP协议)进行通信的应用程序接口(API)。它允许不同系统间的...

    spring+cxf 整合jar包

    5. **Spring MVC集成**:如果你的项目使用了Spring MVC,你可以将CXF服务与控制器结合,提供RESTful API,使得前后端交互更加便捷。 6. **异常处理**:Spring和CXF结合,可以统一处理服务调用中的异常,提供更优雅...

Global site tag (gtag.js) - Google Analytics