Cxf WebService实战

在前一篇转载的关于cxf webservice的实现思路中向大家介绍了实现webservice的思路,但并没有给出具体的实现代码,在本文中我将通过介绍借助于spring实现webservice的方式,在本文中同时将向大家介绍在我实现的过程中遇到的一些问题。

1.搭建webservice服务端:

(1.1)新建java web工程,同时在web.xml中进行spring的相关配置,如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>    
		<servlet-name>cxfService</servlet-name>    
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
	</servlet> 
	<servlet-mapping>    
		<servlet-name>cxfService</servlet-name>    
		<url-pattern>/*</url-pattern>
	</servlet-mapping>
	
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			/WEB-INF/classes/spring/spring.xml
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
</web-app>
(1.2)相关spring文件的具体内容,spring.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
	
	<import resource="spring-util-cxf-server.xml" />
</beans>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jaxws="http://cxf.apache.org/jaxws" 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-3.1.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-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-extension-soap.xml" />
	<import resource="classpath*:META-INF/cxf/cxf-servlet.xml" />

	<bean id="personService" class="server.WSServiceImpl" />
	
	<bean id="inMessageInterceptor" class="com.tgb.lk.util.cxf.server.CxfMessageInterceptor">
		<constructor-arg value="receive" />
	</bean>
	
	<bean id="outLoggingInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
	<!-- 注意下面的address,这里的address的名称就是访问的WebService的name -->
	<jaxws:server id="personWsServer" serviceClass="server.WSService"
		address="/changshou">
		<jaxws:serviceBean>
			<!-- 要暴露的 bean 的引用 -->
			<ref bean="personService" />
		</jaxws:serviceBean>
		<jaxws:inInterceptors>
			<ref bean="inMessageInterceptor" />
		</jaxws:inInterceptors>
		<jaxws:outInterceptors>
			<ref bean="outLoggingInterceptor" />
		</jaxws:outInterceptors>
	</jaxws:server>

</beans>

(1.3)创建相关类,自定义拦截器MyInterceptor.java

package interceptor;

import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;

public class MyInterceptor extends AbstractPhaseInterceptor<Message> {
	// 至少要一个带参的构造函数
	public MyInterceptor(String phase) {
		super(phase);
	}

	/**
	 * 自定义消息拦截器
	 */
	public void handleMessage(Message message) throws Fault {
		System.out.println("############handleMessage##########");
		System.out.println(message);
		if (message.getDestination() != null) {
			System.out.println(message.getId() + "#"
					+ message.getDestination().getMessageObserver());
		}
		if (message.getExchange() != null) {
			System.out.println(message.getExchange().getInMessage() + "#"
					+ message.getExchange().getInFaultMessage());
			System.out.println(message.getExchange().getOutMessage() + "#"
					+ message.getExchange().getOutFaultMessage());
		}
	}
}
实体对象User:

package com.hoo.entity;
import java.io.Serializable;

public class User implements Serializable {
    private static final long serialVersionUID = 677484458789332877L;
    private int id;
    private String name;
    private String email;
    private String address;

    @Override
    public String toString() {
        return this.id + "#" + this.name + "#" + this.email + "#" + this.address;
    }

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

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

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}



	public static long getSerialversionuid() {
		return serialVersionUID;
	}
}

实体对象Users

package com.hoo.entity;
import java.util.HashMap;
import java.util.List;

public class Users {
    private List<User> users;
    private User[] userArr;
    private HashMap<String, User> maps;
	public List<User> getUsers() {
		return users;
	}

	public void setUsers(List<User> users) {
		this.users = users;
	}

	public User[] getUserArr() {
		return userArr;
	}

	public void setUserArr(User[] userArr) {
		this.userArr = userArr;
	}

	public HashMap<String, User> getMaps() {
		return maps;
	}

	public void setMaps(HashMap<String, User> maps) {
		this.maps = maps;
	}
}

创建Webservice接口,WSService.java:

package server;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import com.hoo.entity.User;
import com.hoo.entity.Users;

@WebService
@SOAPBinding(style = Style.RPC)
public interface WSService {
	public void sayHello(String username);
	
   /*********传递复杂对象begin***********/
    public User getUserByName(@WebParam(name = "name") String name);
    public void setUser(User user);
    public Users getUsers(int i);
    public void setUsers(Users users);
   
    /**********传递复杂对象end*************/
}
创建Webservice接口的实现类,WSServiceImpl.java

package server;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import com.hoo.entity.User;
import com.hoo.entity.Users;

@WebService
@SOAPBinding(style = Style.RPC)
public class WSServiceImpl implements WSService {
	@Override
	public void sayHello(String username) {
		System.out.println(username);
	}

    public User getUserByName(@WebParam(name = "name") String name) {
        User user = new User();
        user.setId(new Date().getSeconds());
        user.setName(name);
        user.setAddress("cangzhou");
        user.setEmail(name + "@163.com");
        return user;
    }
    public void setUser(User user) {
        System.out.println("############Server setUser###########");
        System.out.println("setUser:" + user);
    }
    public Users getUsers(int i) {
        List<User> users = new ArrayList<User>();
        for (int j = 0; j <= i; j++) {
            User user = new User();
            user.setId(new Date().getSeconds());
            user.setName("jack#" + j);
            user.setAddress("china");
            user.setEmail("jack" + j + "@hoo.com");
            users.add(user);
        }
        Users u = new Users();
        u.setUsers(users);
        return u;
    }
    public void setUsers(Users users) {
        System.out.println("############Server setUsers###########");
        for (User u : users.getUsers()) {
            System.out.println("setUsers:" + u);
        }
    }
}
将此项目放在tomcat中进行发布,然后通过发布地址测试该webservice是否发布成功,结果如下:


看到此图片证明我们的webservice发布成功,接下来的就让我们搭建客户端对这个webservice进行访问。


2.搭建webservice客户端,如果想在客户端对webservice进行访问我们需要得到webservice发布的接口,这个类我们可以通过jdk自带的命令通过wsdl地址进行导入,具体操作如下:

打开命令窗口,输入如下命令:wsimport -d h: -keep -verbose http://localhost:8080/YCHWebServiceServer/changshou?wsdl,回车即可生成webservice中的相关类(本命令将导出的类放在h盘下的server文件夹中),然后将这些类放入到客户端中,生成的类如下:

新建一个普通的java项目,新建类Client.java,代码如下:

package client;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import client.WSService;

public class Client {
	public static void main(String[] args){
		JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
		factory.setServiceClass(WSService.class);
		//factory.setAddress("http://localhost:8080/YCHWebServiceServer/changshou/changshou");
		factory.setAddress("http://localhost:8080/YCHWebServiceServer/changshou");
		WSService service = (WSService) factory.create();
		/*******sayHello()*******/
		//service.sayHello("xxxx");
		
		/*******getUserByName()方法********/
          User user = service.getUserByName("yangchangshou");
//        System.out.println(user.getAddress());
//        System.out.println(user.getEmail());
//        System.out.println(user.getId());
//        System.out.println(user.getName());
//        System.out.println(user.getClass());
        
          /*******setUser()方法********/
//          user.setAddress("China-Guangzhou");
//          service.setUser(user);
        
          /*******getUsers()方法********/
         Users users = service.getUsers(4);
         for(User u : users.getUsers()){
        	 System.out.println(u.getName());
         }
        
        
	}
}

然后将通过wsdl生成的类放入到与Client.java类同目录下:

注意无论是在服务端还是在客户端都要导入与CXF相关的jar包,运行Client类中的main()方法,我们可以看到输出结果如下:


通过输出结果我们就完成了对webservice的调用。在做本实例的过程中遇到了一个很让人头疼的问题,其实也算不上是什么大问题,由于我在刚开始的时候将web.xml文件中的cxfservice的url-pattern设置成了/changshou/*,而在spring-util-cxf-server.xml文件中我将访问webservice的name定义成了/changshou,实际的放我那地址应该是:http://http://localhost:8080/YCHWebServiceServer/changshou/changshou,而我在客户端的代码中一直使用http://localhost:8080/YCHWebServiceServer/changshou,这样总是报错,错误信息如下:

导致我找了很长时间才找到解决办法,原来真正的访问地址应该是web.xml文件中配置的cxfservice的url-pattern + spring-util-cxf-server.xml文件中的<jaxws:server>标签中的address属性值,也就是如果在web.xml文件中配置的是/*, spring-util-cxf-server.xml文件中配置的是/changshou,那么webservice的地址应该是:http://localhost:8080/YCHWebServiceServer/changshou,而如果web.xml文件中配置的是/changshou/*,那么webservice的地址则应该是:http://localhost:8080/YCHWebServiceServer/changshou/changshou,希望能对遇到同样问题的兄弟有所帮助。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。