您的位置:首页 > 编程语言 > Java开发

轻量级webservice解决方案Jax-ws(集成Spring3)

2014-04-28 13:32 369 查看

背景:

公司一直以来都使用xfire作为webservice通讯组件,它的功能性、稳定性都非常不错,而且通过myeclipse的一些功能生成client也是分分钟的事情,使得开发webservice变得非常便利,这也是我们选择它的原因吧。不过它是一个比较重量级的组件,一旦使用xfire服务端就需要引用非常多的jar包,客户端同样也需要对xfire的jar包进行引用(客户端可能也可以不需要引用xfire的jar,但是目前公司的实现是这样没有深入研究)。本人一直偏爱轻量级的组件,所以一直在找一个轻量级的webservice组件。目前我知道的webservice组件有
Axis 、CXF 、jax-ws等,其中CXF基本上是目前最为主流的组件,Axis已经有些过时了(没有贬低意思),jax-ws则是sun(oracle)公司自己的实现,也是其中最轻的,完全符合我的胃口 哈哈,那么我就为大家介绍一下如何实现吧。

实现目标:

1.完成webservice的基础操作

1.返回自定义对象Bean ,2返回自定义对象列表BeanList,应该已经可以满足95%的需求了吧。

2.和spring进行整合

毕竟spring是目前j2ee最主流的实现嘛,如果你不喜欢使用框架推荐您看一下这篇文章,估计20分钟就能实现java内置的jax-ws了http://www.cnblogs.com/Johness/archive/2013/04/19/3030392.html

spring jax-ws - 服务端教程:

环境介绍:win7 + jdk1.6 + Tomcat6 + spring3.1

1.添加jar包

说明:

添加一个springjax-ws
的整合包即可,(istack-commons-runtime是由于出现问题后添加的,所以如果在本机的环境中没有此问题可不添加)

<!-- jax-ws -->
<dependency>
	<groupId>org.jvnet.jax-ws-commons.spring</groupId>
	<artifactId>jaxws-spring</artifactId>
	<version>1.8</version>
	<!-- 排除其对spring2.0的依赖 -->
	<exclusions>
		<exclusion>
			<groupId>org.springframework</groupId>
			artifactId>spring</artifactId>
		</exclusion>
	</exclusions>
</dependency>
<!-- jax-ws :解决 noclass XMLStreamReaderToContentHandler问题(添加jaxws-rt也可以解决noclass问题,但会出现xsd文件异常) -->
<dependency>
<span style="white-space:pre">	</span><groupId>com.sun.istack</groupId>
<span style="white-space:pre">	</span><artifactId>istack-commons-runtime</artifactId>
<span style="white-space:pre">	</span><version>2.2.1</version>
</dependency>


2.定义接口

说明:

定义一个webservice接口(targetNamspace 规则一般使用倒package格式)

package com.metecyu.yusr.ws;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import com.metecyu.yusr.ws.model.WsUser;
import com.metecyu.yusr.ws.model.WsUserList;

@WebService(name = "YusrWsServiceItf", targetNamespace = "http://ws.yusr.metecyu.com/")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface YusrWsServiceItf {
<span style="white-space:pre">	</span>
    /**
     * 获取用户对象
     * @param userid
     * @return
     *     returns testjws.client.WsUser
     */
    @WebMethod
    public WsUser getUser(
        @WebParam(name = "userid", partName = "userid")
        String userid);

    /**
     * 获取部门用户列表
     * @param deptid
     * @return
     *     returns testjws.client.WsUserList
     */
    @WebMethod
    public WsUserList getDeptUserList(
        @WebParam(name = "deptid", partName = "deptid")
        String deptid);

}


3.定义服务实现

根据接口实现业务内容,其中的@webService serviceName是以后生成客户端的类名,portName是获取实现实例的方法名称。

备注:方法返回对象推荐不要直接使用hibernate的model,原因是model对象中会有很多关联对象等比较复杂,而且不利于对象属性权限控制,所以推荐另外定义一个wsmodel,而且去掉model中不必要的属性,也有助于ws调用的效率。

package com.metecyu.yusr.ws;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.jws.WebService;
import org.springframework.stereotype.Component;
import com.metecyu.yusr.bmodel.UserD;
import com.metecyu.yusr.model.User;
import com.metecyu.yusr.service.UserService;
import com.metecyu.yusr.ws.model.WsUser;
import com.metecyu.yusr.ws.model.WsUserList;
  
  
@WebService(endpointInterface="com.metecyu.yusr.ws.YusrWsSeviceItf",  
            serviceName="yusrWsService",  
            portName="yusrWsServicePort",  
            targetNamespace="http://ws.yusr.metecyu.com")  
	//该对象交由spring管理,studentWsService即为该实现类在bean容器中的name  
	@Component("yusrWsSeviceImpl")  
	public class YusrWsSeviceImpl implements YusrWsSeviceItf{ 
	@Resource
	UserService userService;

    @Override
    public WsUser getUser(String id) {
    	User user =this.userService.findById(id);
    	WsUser ws = this.userService.turnToWsUser(user);
    	return ws;
    }
    @Override
    public WsUserList getDeptUserList(String deptid) {
    	List<UserD>  userList = userService.findDeptUser(deptid);
    	ArrayList<WsUser> outList = new ArrayList();
    	/**/
    	for(UserD user :userList){
    		WsUser ws = this.userService.turnToWsUser(user);
    		outList.add(ws);
    	}
    	WsUserList usrList= new WsUserList();
    	usrList.userList = outList;
    	return usrList;
    }
}


4.webservice配置

添加一个spring的配置文件applicationContext-jaxws.xml。配置一个webservice的url,关联一个业务实现bean,就这么简单。

<?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:ws="http://jax-ws.dev.java.net/spring/core"  
        xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"  
        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-3.0.xsd    
           http://jax-ws.dev.java.net/spring/core http://jax-ws.java.net/spring/core.xsd  
           http://jax-ws.dev.java.net/spring/servlet http://jax-ws.java.net/spring/servlet.xsd ">              
    <context:annotation-config/> 
    <context:component-scan base-package="com.metecyu.yusr"/>  
     <!-- 这个错误是因为xsd的地址访问不到,不影响 -->
    <wss:binding url="/jaxws-spring">
        <wss:service>    
			<!-- bean的值需要加前缀 "#",studentWsService是实现类在bean容器中的名称 -->   
            <ws:service bean="#yusrWsServiceImpl"> 
            </ws:service>  
        </wss:service>  
    </wss:binding>     
</beans>


2 在web.xml中添加一个servlet,对应applicationContext-jaxws.xml的url。

<servlet>  
	    <servlet-name>springWsServlet</servlet-name>  
	    <servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>  
	</servlet>  
	<servlet-mapping>  
	    <servlet-name>springWsServlet</servlet-name>  
	    <url-pattern>/jaxws-spring</url-pattern>  
	</servlet-mapping>


5.测试服务

现在服务端的程序已经全部完成了,如果没有问题的话启动Tomcat后可以查看一下wsdlhttp://localhost:8080/yusr/jaxws-spring?wsdl

<!--
 Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3-b02-. 
-->
<!--
 Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3-b02-. 
-->
<definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://ws.yusr.metecyu.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://ws.yusr.metecyu.com" name="yusrWsSevice">
<import namespace="http://ws.yusr.metecyu.com/" location="http://localhost:8080/yusr/jaxws-spring?wsdl=1"/>
<binding xmlns:ns1="http://ws.yusr.metecyu.com/" name="yusrWsSevicePortBinding" type="ns1:YusrWsServiceItf">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="getUser">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal" namespace="http://ws.yusr.metecyu.com/"/>
</input>
<output>
<soap:body use="literal" namespace="http://ws.yusr.metecyu.com/"/>
</output>
</operation>
<operation name="getDeptUserList">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal" namespace="http://ws.yusr.metecyu.com/"/>
</input>
<output>
<soap:body use="literal" namespace="http://ws.yusr.metecyu.com/"/>
</output>
</operation>
</binding>
<service name="yusrWsSevice">
<port name="yusrWsSevicePort" binding="tns:yusrWsSevicePortBinding">
<soap:address location="http://localhost:8080/yusr/jaxws-spring"/>
</port>
</service>
</definitions>

spring jax-ws - 客户端实现:

1.生成客户端代码

生成客户端代码有没有像myeclipse这样的工具可以用啊,说实话我没有试过。不过我找到一个更好的工具wsimport,它是jdk1.6中提供的工具。我们来看看他是如何使用的吧。

步骤:

1 .path中配置jdk的bin

2. 建立生成文件的目录(为了方便 ,我在桌面新建了src目录、在src目录中新建classes目录)

3.在cmd中执行生成代码的语句:

wsimport -keep -p testjws.client http://localhost:8080/yusr/jaxws-spring?wsdl -target
2.0 -s .\src

4.成功以后在 src/testjws/client目录下就会存在生成调用jax-ws的类了(如图)

参数说明:

-s 源文件的目录

-p package名称

其它参数:

-d .\src\classes
可以生成classes



2.调用客户端

把生成的代码添加至项目中,然后编写调用代码。

package testjws.client.main;
import testjws.client.WsUser;
import testjws.client.WsUserList;
import testjws.client.YusrWsService;
import testjws.client.YusrWsServiceItf;

public class Main {

	public static void main(String[] args) {
		
		YusrWsServiceItf service = new YusrWsService().getYusrWsServicePort();		
		long st = System.currentTimeMillis();
		// 自定义单个对象定义
		WsUser user = service.getUser("yh1");
		System.out.println("用户姓名:"+user.getUsername());
		long end = System.currentTimeMillis();
		System.out.println("用时:"+(end -st));		
		
		// 列表对象
		WsUserList wsUserList = service.getDeptUserList("dept1");
		System.out.println("\n部门用户数量:"+ wsUserList.getUserList().size());
		for(WsUser usr : wsUserList.getUserList()){
			System.out.println(usr.getUsername());
		}
	}

}


参考资料:

1 JAX与spring的无缝集成(一) http://schy-hqh.iteye.com/blog/1923934

这是本教程主要参考的文档。
2 添加 jaxws-spring、istack-commons-runtime 以后后台一共会添加的jar。jar相对xfire是不是稍多了,不过这只是服务器端才需要的jar包。使用jax-ws的优势在于客户端调用时则不需要任何jar包,只需要一个jdk就好了(jdk-1.6以上),这才是jax-ws的优势。

activation-1.1.jar
istack-commons-runtime-2.2.1.jar
jaxb-api-2.1.jar
jaxb-impl-2.1.2.jar
jaxws-api-2.1.jar
jaxws-rt-2.1.3.jar
jaxws-spring-1.8.jar
jsr181-api-1.0-MR1.jar
jsr250-api-1.0.jar
mimepull-1.1.jar
resolver-20050927.jar
saaj-api-1.3.jar
saaj-impl-1.3.jar
sjsxp-1.0.jar
stax-api-1.0-2.jar
stax-ex-1.0.jar
streambuffer-0.4.jar
xbean-spring-2.7.jar
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: