在java中使用spring整合cxf实现webservice

转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/53169020
本文出自【我是干勾鱼的博客

java中实现webservice有两种常用的方式,一种是cxf,另一种是axis。这两种方式的区别大家可以自己在网上找找参考一下。cxf可以与spring进行整合,是一款不错的webservice产品。今天给大家讲解一下使用spring整合cxf实现webservice的方法。

1 创建服务器端程序

1.1 新建一个web工程

1.1.1 工程环境所依赖的各软件的版本

首先需要新建一个web工程,工程运行环境为:

  • java:1.7.0_65

  • tomcat:apache-tomcat-6.0.47

  • eclipse:Luna Service Release 2 (4.4.2)

  • cxf:3.1.8

  • 操作系统:win7

先给大家看一下eclipse中生成的服务器端程序:

这里写图片描述

注意将下载之后的cxf的3.1.8版本lib里的所有jar包都拷贝到项目中,并建立引用关系,笔者这里就是上图“Libraries”中的“WebServiceServer”库。

1.1.2 创建pojo

先写一个pojo,即文件Person.java

package com.yhd.webservice.cxf.server.poto;

/**
 * 类名称:Persion.java<br>
 * 类描述:<br>
 * 创建时间:2016年11月11日, 下午2:48:45
 * 
 * @version 1.0
 * @since JDK1.7.0_65
 * @author yhd
 */

public class Person {
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}
1.1.3 创建接口

定义一个接口,即文件PersonService.java

package com.yhd.webservice.cxf.server.service;

import java.util.List;

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

import com.yhd.webservice.cxf.server.poto.Person;

/**
 * 类名称:PersonService.java<br>
 * 类描述:<br>
 * 创建时间:2016年11月11日, 下午2:43:36
 * 
 * @version 1.0 
 * @since JDK1.7.0_65
 * @author yhd
 */

@WebService
public interface PersonService {

        public List<Person> findAll(@WebParam(name = "arg0") String name); 

}
1.1.4 接口实现类

接口类的实现,即文件PersonServiceImp.java

package com.yhd.webservice.cxf.server.service.impl;

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

import javax.jws.WebService;

import com.yhd.webservice.cxf.server.poto.Person;
import com.yhd.webservice.cxf.server.service.PersonService;

/**
 * 类名称:PersonServiceImp.java<br>
 * 类描述:<br>
 * 创建时间:2016年11月11日, 下午2:47:53
 * 
 * @version 1.0 
 * @since JDK1.7.0_65
 * @author yhd
 */

@WebService(endpointInterface="com.yhd.webservice.cxf.server.service.PersonService",serviceName="person")
public class PersonServiceImp implements PersonService {

    @Override
    public List<Person> findAll(String name){  
        ArrayList<Person> persons = new ArrayList<Person>();  

        Person p1 = new Person();
        p1.setName(name + "3");
        p1.setAge(18);

        Person p2 = new Person();
        p2.setName(name + "4");
        p2.setAge(20);

        persons.add(p1);
        persons.add(p2);

        return persons;  
    }  
}
1.1.5 spring配置文件application-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<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-2.5.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"
    xmlns="http://www.springframework.org/schema/beans">

    <bean id="jaxWsServiceFactoryBean" class="org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean">
        <property name="wrapped" value="true" />
    </bean>

    <jaxws:endpoint id="serviceimp" address="/person"
        implementor="com.yhd.webservice.cxf.server.service.impl.PersonServiceImp">

        <jaxws:serviceFactory>
            <ref bean="jaxWsServiceFactoryBean" />
        </jaxws:serviceFactory>
    </jaxws:endpoint>
</beans>

这里要注意,网上很多配置cxf的参考文章都提到要将三个配置信息放到spring的配置文件中:

<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最新版3.1.8,如果加上:

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

反而会报错:

严重: Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:META-INF/cxf/cxf-extension-soap.xml]

网上说cxf3.0之后可能已经不需要这个文件了,将这个文件去掉就可以了。或者将这三个配置都去掉也可以。笔者将这三者都去掉了,可以使用。

1.1.6 配置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="WebApp_ID" version="3.0">
  <display-name>WebServiceServer</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

  <display-name>cxfTest</display-name>  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>/WEB-INF/application-context.xml</param-value>  
    </context-param>  
    <listener>  
        <listener-class>  
            org.springframework.web.context.ContextLoaderListener     
        </listener-class>  
    </listener>  
    <servlet>  
        <servlet-name>CXFServlet</servlet-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>/hello/*</url-pattern>  
    </servlet-mapping>

</web-app>

这里面配置了spring的监听器,又配置了一个cxf的servlet。

1.2 启动web工程

笔者这里在tomcat中配置了web工程的端口号为8081,并且将8081直接指向eclipse中工程的地址,所以访问该工程时就不用再输入工程名了。

启动tomcat。在浏览器里输入:

http://localhost:8081/hello

如上所示,没有再输入工程名“WebServiceServer”。

这时浏览器页面会出现:

这里写图片描述

能看到“person”前有一个倒过来的类包的名称。

这说明服务器端已经创建成功!

2 生成服务器端接口类

2.1 安装cxf

cxf官网下载cxf的3.1.8版本,笔者下载的zip版。将文件解压缩并放到一个合适的目录下。在环境变量中加入变量“CXF_HOME”,值就是安装路径;再在“PATH”变量中加入:

%CXF_HOME%\bin

这样cxf的命令就可以使用了。

2.2 使用“wsdl2java”命令生成接口类

wsdl2java的用法如下:

wsdl2java –p 包名 –d 目录名 wsdl路径

具体的意义如下:

  • -p:指定其wsdl的命名空间,也就是要生成代码的包名

  • -d:指定要产生代码所在目录

  • -client 生成客户端测试web service的代码

  • -server:生成服务器启动web service的代码

  • -impl:生成web service的实现代码

  • -ant:生成build.xml文件

  • -compile:生成代码后编译

  • -quient:静默模式,不输出警告与错误信息

  • -all:生成所有开始端点代码:types,service proxy,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.

笔者这里的命令为:

wsdl2java -p com.yhd.webservice.cxf.client.info -d D:\test http://localhost:8081/hello/person?wsdl

执行之后就会在-d后面的路径下生成相应的类。

2.3 将接口类拷贝到客户端项目中

将这些类拷贝到后面新创建的客户端项目中。

有的时候生成了类之后,将这些类拷贝到客户端项目,类中的某些super()会报错。这就需要再加上“-frontend jaxws21”命令,也就是将命令写为:

wsdl2java -frontend jaxws21 -p com.yhd.webservice.cxf.client.info -d D:\test http://localhost:8081/hello/person?wsdl

再生成的类就不会报错了。

3 创建客户端程序

客户端我们就做一个简单的程序。

依然创建一个web项目(其实创建一个java项目就可以了),依赖的类与服务器端一样,将cxf的jar包都拷贝进去,程序如下:

这里写图片描述

将服务器端生成的接口类拷贝过来,然后再创建一个“ClientTest.jar”文件,内容如下:

package com.yhd.webservice.cxf.client.main;

import java.util.List;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import com.yhd.webservice.cxf.client.info.Person;
import com.yhd.webservice.cxf.client.info.PersonService;

/**
 * 类名称:ClientTest.java<br>
 * 类描述:<br>
 * 创建时间:2016年11月15日, 上午10:04:16
 * 
 * @version 1.0 
 * @since JDK1.7.0_65
 * @author yhd
 */

public class ClientTest {

    public static void main(String[] args) {

        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(PersonService.class);
        factory.setAddress("http://localhost:8081/hello/person");
        PersonService service = (PersonService)factory.create();
        List<Person> list = (List<Person>)service.findAll("张");

        for(Person person : list) {
            System.out.println("name=" + person.getName());
            System.out.println("age=" + person.getAge());
            System.out.println("-------------------");
        }
    }

}

4 运行客户端程序

在服务器端保持运行的状态下,运行客户端程序。正常的话,会打印出:

name=张3
age=18
-------------------
name=张4
age=20
-------------------

有一点要注意,一方面,一定要保持客户端和服务器端使用的jdk版本是一致的,另一方面,cxf从3.1开始已经不支持jdk的1.6版本了,而至少是jdk的1.7或者是以上的版本。所以我们的项目里的jdk至少需要使用jdk的1.7版本,否则比如使用1.6,有可能会报错:

Caused by: java.lang.UnsupportedClassVersionError: org/apache/cxf/jaxws/spring/NamespaceHandler : Unsupported major.minor version 51.0
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.security.SecureClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access 000(UnknownSource)atjava.net.URLClassLoader 1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1191)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1669)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1547)
at org.springframework.util.ClassUtils.forName(ClassUtils.java:266)
at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:124)

这一点大家要注意。

5 关于附件源代码

文章中服务器端程序和客户端程序的源代码都放在了笔者github的网站里面,其中:

服务器端程序位于:

https://github.com/yuhaidong/WebServiceServer

客户端程序位于:

https://github.com/yuhaidong/WebServiceClient

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值