CXF [web service]整合spring 总结

大概花费了一周的时间来了解web service 这个东东,从开始的axis2 ,到xFire ,到最后选择了CXF,一切的资料都是来自于网络资料,由于要和spring整合,因此最后选择了CXF,

我是用的是myeclipse6.5版本,导入cxf的jar包开发的时候出现了众多的问题,网上说的是java EE里面的javaee.jar里面jar包的问题,最后整个删掉了java EE  lib,可是在myeclipse7.5就没问题, 有意思的是最后我又把这个java EE 的LIB导入了,嘿嘿 没有报错了。这东西应该还是有用的,还是不删为好啊,所以到这里建议大家使用7.5版本的,似乎6.5版本有bug。

1. 首先确定下来使用CXF 需要哪些jar包:

 

以上两幅图,左图是最终使用的,右图是开始开发时,遇到问题后加入的,但最后测试,使用左图即可。

2.控制台报错整理:

严重: Servlet.service() for servlet CXFServlet threw exception
java.lang.NoClassDefFoundError: org/apache/xml/serializer/TreeWalker

解决:导入serializer-2.7.1.jar  。

 严重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloWorld': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.apache.cxf.binding.soap.SoapTransportFactory' defined in class path resource [META-INF/cxf/cxf-extension-soap.xml]: Unsatisfied dependency expressed through constructor argument with index 2 of type [java.lang.String]: Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments?

解决:导入:neethi-3.0.1.jar   。

涉及到的配置文件修改:

1.web.xml :

在web.xml中增加如下代码:(我的spring容器配置文件是applicationContext.xml  放置在src下面。)

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   WEB-INF/classes/applicationContext.xml
  </param-value>
 </context-param>

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

 <servlet>
  <servlet-name>CXFServlet</servlet-name>
  <display-name>CXFServlet</display-name>
  <servlet-class>
   org.apache.cxf.transport.servlet.CXFServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>CXFServlet</servlet-name>
  <url-pattern>/webservice/*</url-pattern>
 </servlet-mapping>

2. applicationContext.xml:

最终的该文件完整内容为:(当然这里没有其他bean的配置, 只是个实例而已 ,该实例的名称为:cxf_Demo1)

<?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.xsd
                       http://cxf.apache.org/jaxwshttp://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" />

 <jaxws:endpoint id="helloWorld"
  implementor="com.demo.HelloWorldImpl" address="/helloWorld" />

 <bean id="client" class="com.demo.HelloWorld"
  factory-bean="clientFactory" factory-method="create" />

 <bean id="clientFactory"
  class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
  <property name="serviceClass" value="com.demo.HelloWorld" />
  <property name="address"
   value="
http://localhost:8080/cxf_Demo1/webservice/helloWorld" />
 </bean>
</beans>

 

3.思路:

建立webservice 接口:普通java接口,在建立该接口的实现类。然后暴露该接口。详细代码如下:

 

package com.demo;

public class User {
 
	private String name;
	private String description;
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the description
	 */
	public String getDescription() {
		return description;
	}
	/**
	 * @param description the description to set
	 */
	public void setDescription(String description) {
		this.description = description;
	}
	
	
}
package com.demo;

import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebService;

@WebService
public interface HelloWorld {

	String sayHi(@WebParam(name="text")String text);
    String sayHiToUser(User user);
    String[] SayHiToUserList(List<User> userList);

}


 

package com.demo;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.jws.WebService;

@WebService(endpointInterface = "com.demo.HelloWorld", serviceName = "HelloWorld")
public class HelloWorldImpl implements HelloWorld {

	Map<Integer, User> users = new LinkedHashMap<Integer, User>();

	public String sayHi(String text) {
		return "Hello " + text;
	}

	public String sayHiToUser(User user) {
		users.put(users.size() + 1, user);
		return "Hello " + user.getName();
	}

	public String[] SayHiToUserList(List<User> userList) {
		String[] result = new String[userList.size()];
		int i = 0;
		for (User u : userList) {
			result[i] = "Hello " + u.getName();
			i++;
		}
		return result;
	}

}
package com.demo;

import javax.xml.ws.Endpoint;

public class webServiceApp {

	/**
	 * @author zhangxiaojun
	 * @version Sep 19, 2011 9:10:25 AM
	 * @param args
	 *            TODO:
	 */
	public static void main(String[] args) {
		System.out.println("web service start");
		HelloWorldImpl implementor = new HelloWorldImpl();
		String address = "http://localhost:8080/helloWorld";
		Endpoint.publish(address, implementor);
		System.out.println("web service started");

	}

}
package com.demo;

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

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class HelloWorldClient {

	/**
	 * @author  zhangxiaojun 
	 * @version Sep 19, 2011  10:42:49 AM
	 * @param args
	 * TODO:
	 */
	public static void main(String[] args) {
//		JaxWsProxyFactoryBean svr = new JaxWsProxyFactoryBean();
//		svr.setServiceClass(HelloWorld.class);
//		svr.setAddress("http://localhost:8080/helloWorld");
//		HelloWorld hw = (HelloWorld) svr.create();
//		User user = new User();
//		user.setName("Tony");
//		user.setDescription("test");
//		System.out.println(hw.sayHiToUser(user));
		
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
		HelloWorld client = (HelloWorld)context.getBean("client");
        User user1 = new User();
        user1.setName("Tony");
        user1.setDescription("test");
        User user2 = new User();
        user2.setName("freeman");
        user2.setDescription("test");
        List<User> userList= new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);
        String[] res = client.SayHiToUserList(userList);
        System.out.println(res[0]);
        System.out.println(res[1]);          




	}

}

在没有整合到spring的时候,通过以上代码段的客户端和服务器端代码,先启动服务器端代码:com.demo.webServiceApp.java   ,在启动客户端代码:com.demo.HelloWorldClient.java   可以查看到控制台输出的结果。 

当整合到spring后,部署到tomcat之后,启动浏览器 输入:http://localhost:8080/cxf_Demo1/webservice/helloWorld?wsdl   就可以 看到如下内容:

  <?xml version="1.0" encoding="UTF-8" ?> 
- <wsdl:definitions name="HelloWorld" targetNamespace="http://demo.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://demo.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
- <wsdl:types>
- <xs:schema targetNamespace="http://jaxb.dev.java.net/array" version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:complexType final="#all" name="stringArray">
- <xs:sequence>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="item" nillable="true" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  </xs:schema>
- <xs:schema attributeFormDefault="unqualified" elementFormDefault="unqualified" targetNamespace="http://demo.com/" xmlns="http://demo.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
- <xs:complexType name="user">
- <xs:sequence>
  <xs:element minOccurs="0" name="description" type="xs:string" /> 
  <xs:element minOccurs="0" name="name" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="SayHiToUserList" type="SayHiToUserList" /> 
- <xs:complexType name="SayHiToUserList">
- <xs:sequence>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="arg0" type="user" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="SayHiToUserListResponse" type="SayHiToUserListResponse" /> 
- <xs:complexType name="SayHiToUserListResponse">
- <xs:sequence>
  <xs:element maxOccurs="unbounded" minOccurs="0" name="return" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="sayHi" type="sayHi" /> 
- <xs:complexType name="sayHi">
- <xs:sequence>
  <xs:element minOccurs="0" name="text" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="sayHiResponse" type="sayHiResponse" /> 
- <xs:complexType name="sayHiResponse">
- <xs:sequence>
  <xs:element minOccurs="0" name="return" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="sayHiToUser" type="sayHiToUser" /> 
- <xs:complexType name="sayHiToUser">
- <xs:sequence>
  <xs:element minOccurs="0" name="arg0" type="user" /> 
  </xs:sequence>
  </xs:complexType>
  <xs:element name="sayHiToUserResponse" type="sayHiToUserResponse" /> 
- <xs:complexType name="sayHiToUserResponse">
- <xs:sequence>
  <xs:element minOccurs="0" name="return" type="xs:string" /> 
  </xs:sequence>
  </xs:complexType>
  </xs:schema>
  </wsdl:types>
- <wsdl:message name="sayHiToUserResponse">
  <wsdl:part element="tns:sayHiToUserResponse" name="parameters" /> 
  </wsdl:message>
- <wsdl:message name="SayHiToUserList">
  <wsdl:part element="tns:SayHiToUserList" name="parameters" /> 
  </wsdl:message>
- <wsdl:message name="sayHiResponse">
  <wsdl:part element="tns:sayHiResponse" name="parameters" /> 
  </wsdl:message>
- <wsdl:message name="sayHi">
  <wsdl:part element="tns:sayHi" name="parameters" /> 
  </wsdl:message>
- <wsdl:message name="sayHiToUser">
  <wsdl:part element="tns:sayHiToUser" name="parameters" /> 
  </wsdl:message>
- <wsdl:message name="SayHiToUserListResponse">
  <wsdl:part element="tns:SayHiToUserListResponse" name="parameters" /> 
  </wsdl:message>
- <wsdl:portType name="HelloWorld">
- <wsdl:operation name="SayHiToUserList">
  <wsdl:input message="tns:SayHiToUserList" name="SayHiToUserList" /> 
  <wsdl:output message="tns:SayHiToUserListResponse" name="SayHiToUserListResponse" /> 
  </wsdl:operation>
- <wsdl:operation name="sayHi">
  <wsdl:input message="tns:sayHi" name="sayHi" /> 
  <wsdl:output message="tns:sayHiResponse" name="sayHiResponse" /> 
  </wsdl:operation>
- <wsdl:operation name="sayHiToUser">
  <wsdl:input message="tns:sayHiToUser" name="sayHiToUser" /> 
  <wsdl:output message="tns:sayHiToUserResponse" name="sayHiToUserResponse" /> 
  </wsdl:operation>
  </wsdl:portType>
- <wsdl:binding name="HelloWorldSoapBinding" type="tns:HelloWorld">
  <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> 
- <wsdl:operation name="SayHiToUserList">
  <soap:operation soapAction="" style="document" /> 
- <wsdl:input name="SayHiToUserList">
  <soap:body use="literal" /> 
  </wsdl:input>
- <wsdl:output name="SayHiToUserListResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
- <wsdl:operation name="sayHi">
  <soap:operation soapAction="" style="document" /> 
- <wsdl:input name="sayHi">
  <soap:body use="literal" /> 
  </wsdl:input>
- <wsdl:output name="sayHiResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
- <wsdl:operation name="sayHiToUser">
  <soap:operation soapAction="" style="document" /> 
- <wsdl:input name="sayHiToUser">
  <soap:body use="literal" /> 
  </wsdl:input>
- <wsdl:output name="sayHiToUserResponse">
  <soap:body use="literal" /> 
  </wsdl:output>
  </wsdl:operation>
  </wsdl:binding>
- <wsdl:service name="HelloWorld">
- <wsdl:port binding="tns:HelloWorldSoapBinding" name="HelloWorldImplPort">
  <soap:address location="http://localhost:8080/cxf_Demo1/webservice/helloWorld" /> 
  </wsdl:port>
  </wsdl:service>
  </wsdl:definitions>


然后再启动客户端:com.demo.HelloWorldClient.java   则在控制台能够看到输出的结果:Hello Tony      Hello freeman

最后发现,如果执行该客户端的话, 还得删除 java EE 的lib。晕。否则报如下错:

信息: Creating Service {http://demo.com/}HelloWorldService from class com.demo.HelloWorld
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/activation/registries/LogSupport

 并且需要导入如下cxf 的三个包,否则也要报错:

报错内容:

信息: Creating Service {http://demo.com/}HelloWorld from class com.demo.HelloWorld
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'helloWorld': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
Related cause: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.apache.cxf.binding.soap.SoapTransportFactory' defined in class path resource [META-INF/cxf/cxf-extension-soap.xml]: Unsatisfied dependency expressed through constructor argument with index 2 of type [java.lang.String]: Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments?

===============================================

总算一周时间没有白费,基本搞定啦。在努力!



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值