Web Service服务器和客户端实现

一、概念定义

Web Service是一个平台独立的,低耦合的,自包含的、基于可编程的web应用程序,可使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。

简单对象访问协议(Simple Object Access Protocol,SOAP)是一种基于 XML 的协议,可以和现存的许多因特网协议和格式结合使用,包括HTTP,SMTP,MIME,基于“通用”传输协议是 SOAP的一个优点。它还支持从消息系统到远程过程调用RPC等大量的应用程序。SOAP提供了一系列的标准,如WSRM(WS-Reliable Messaging)确保可靠性与安全性,确保异步处理与调用;WS-Security、WS-Transactions和WS-Coordination等标准提供了上下文信息与对话状态管理。

REST(Representational State Transfer)一种轻量级的Web Service架构,可以完全通过HTTP协议实现。其实现和操作比SOAP和XML-RPC更为简洁,还可以利用缓存Cache来提高响应速度,性能、效率和易用性上都优于SOAP协议。 RESTful 简化了 web service 的设计,它不再需要 wsdl ,也不再需要 soap 协议,而是通过最简单的 http 协议传输数据 ( 包括 xml 或 json) 。既简化了设计,也减少了网络传输量(因为只传输代表数据的 xml 或 json ,没有额外的 xml 包装)。REST架构对资源的操作包括获取、创建、修改和删除资源的操作正好对应HTTP协议提供的GET、POST、PUT和DELETE方法(Verb)。

Restful与SOAP的区别
安全性:SOAP会好于REST
效率和易用性(REST更胜一筹) 
成熟度(总的来说SOAP在成熟度上优于REST)

二、框架对比

参考文档:https://blog.csdn.net/xybelieve1990/article/details/50955230

1、JWS是Java语言对WebService服务的一种实现,用来开发和发布服务。而从服务本身的角度来看JWS服务是没有语言界限的。但是Java语言为Java开发者提供便捷发布和调用WebService服务的一种途径,java6才开始支持。

2、Axis2是Apache下的一个重量级WebService框架,准确说它是一个Web Services / SOAP / WSDL 的引擎,是WebService框架的集大成者,它不但能制作和发布WebService,而且可以生成Java和其他语言版WebService客户端和服务端代码。这是它的优势所在。但是,这也不可避免的导致了Axis2的复杂性,使用过的开发者都知道,它所依赖的包数量和大小都是很惊人的,打包部署发布都比较麻烦,不能很好的与现有应用整合为一体。但是如果你要开发Java之外别的语言客户端,Axis2提供的丰富工具将是你不二的选择。

3、CXF是Apache旗下一个重磅的SOA简易框架,它实现了ESB(企业服务总线)。CXF来自于XFire项目,经过改造后形成的,就像目前的Struts2来自WebWork一样。可以看出XFire的命运会和WebWork的命运一样,最终会淡出人们的视线。CXF不但是一个优秀的Web Services / SOAP / WSDL 引擎,也是一个不错的ESB总线,为SOA的实施提供了一种选择方案,当然他不是最好的,它仅仅实现了SOA架构的一部分。

三、服务端实现

1、JWS实现

WebService.java

import javax.jws.WebMethod;

@javax.jws.WebService
public interface WebService {
	
	@WebMethod
	String setService(String request);

}

WebServiceImpl.java

package webservices;

import javax.jws.WebParam;
import webservices.WebService;
import webservices.Treasury;

@javax.jws.WebService
public class WebServiceImpl implements WebService {

	@Override
	public String setService(@WebParam(name="request")String request){		
		Treasury treasury = new Treasury();		
		String result = treasury.setService(request);
		return result;
	}
}

WebServicePublish.java

package webservices;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.xml.ws.Endpoint;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import webservices.serviceImpl.WebServiceImpl;
import webservices.util.IpUtil;

public class WebServicePublish {
	private static Logger log = Logger.getLogger(WebServicePublish.class);  
	
	public static void main(String[] args) {	
		try {
	        String ipAddress = InetAddress.getLocalHost().getHostAddress();
	        
	        if (IpUtil.isIPv6Address(ipAddress)) {
	        	ipAddress = "["+ipAddress+"]";	            
            }
	        
	        String address = "http://"+ipAddress+":8080/webservices";			
			Endpoint.publish(address , new WebServiceImpl());	
			log.info("webService publish success ^_^ url:"+address);
        } catch (UnknownHostException e) {
	       log.error("get local host ipaddress error:"+e);	    
        }				
    }
}

注意:JWS有很多的注解适配,可参考:https://www.jianshu.com/p/d9a59a99f097
如在WebServiceImpl配置
@javax.jws.WebService( targetNamespace="http://webservice",
                       name="webservicesPortType",
                       serviceName="webservices",
                       portName="webservicesHttpSoap12" 
                      )
@javax.jws.soap.SOAPBinding(style=Style.DOCUMENT,parameterStyle=ParameterStyle.WRAPPED)
@BindingType(value =SOAPBinding.SOAP12HTTP_BINDING)

2、Axis2实现

参考:https://blog.csdn.net/qq877507054/article/details/61922139

3、CXF实现

参考:https://www.cnblogs.com/yg_zhang/p/5928951.html

四、客户端实现

1、wsimport生成客户端
JDK提供了一个wsimport.exe的命令,主要是用于将WebService生成客户端代码,然后好调用WebService。
wsimport是根据JDK1.6.0_21及以上的生成本地代码的,它只能解析服务器端的SOAP协议为1.1,不能解析SOAP1.2的协议。如果解析SOAP1.2 将会解析不完全。
用法:前提是已经将JDK配置为了path环境变量  C:\Documents and Settings\Administrator>wsimport -s D:\test -p webservice http://localhost:30823/server/webservices?wsdl
参数解释:
 -s 后面指定生成源码文件的路径,
    -p 自定义类包 http://localhost:8080/server/webservices?wsdl 是wsdl的路径。
 -d 后面指定生成class文件的路径

2、Axis2生成客户端
1、 下载axis包(http://axis.apache.org/axis2/java/core/download.html),比如当前版本为axis2-1.7.9,解压至本地。
2、 打开cmd,进入axis2-1.7.9\bin目录下,执行命令:
wsdl2java -uri http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx?wsdl -p cn.com.webxml -o train
如:wsdl2java -uri http://localhost:30823/server/webservices?wsdl -o D:\\test
       wsdl2java -uri D:\\test\\webservices.xml -o D:\\test
参数解释:
-uri表示参数指定了wsdl文件的路径,可以是本地路径,也可以是网络路径
-p参数指定了生成的Java类的包名
-o参数指定了生成的一系列文件保存的根目录
3、在执行完上面的命令后,就会发现在当前目录下多了个src目录拷贝整个文件夹放置工程目录下,并将axis2-1.7.9\lib下的lib包引入到工程中。
4、编写客户端调用代码,参照内容如下:

package webservice;
import java.rmi.RemoteException;
import org.apache.axis2.AxisFault;
import webservices.WebServiceImplServiceStub.SetServiceE;
import webservices.WebServiceImplServiceStub.SetServiceResponseE;

public class Client {
	
	public static void main(String[] args){
		
		WebServiceImplServiceStub stub = null;
		try {
	        stub = new WebServiceImplServiceStub();
	        
	        SetServiceE setServiceE = new SetServiceE();
	        
	        WebServiceImplServiceStub.SetService setService = new WebServiceImplServiceStub.SetService();
			
			String request= "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request  number=\"ID-0601-170922-0029\"   time=\"2019-02-22 09:15:34\" ></request>";
			
			setService.setRequest(request);
			
			setServiceE.setSetService(setService);	
			
			SetServiceResponseE setServiceResponseE = stub.setService(setServiceE);
			
			System.out.println(setServiceResponseE.getSetServiceResponse().get_return());          
	        
        } catch (AxisFault e) {	  
        	
	        e.printStackTrace();
	        
        }catch (RemoteException e) {  
        	
            e.printStackTrace();
            
        }		
		
    }
}

3、CFX生成客户端
1、 下载cxf包(http://cxf.apache.org/download.html),比如当前版本为apache-cxf-3.3.0,解压至本地。
2、 打开cmd,进入apache-cxf-3.3.0\bin目录下,执行命令:
wsdl2java -d D:\\src -client http://api.xxx.cn/****/service/registerService?wsdl
如:wsdl2java -d D:\\test -client http://localhost:30823/server/webservices?wsdl
参数解释:
-p  指定其wsdl的命名空间,也就是要生成代码的包名:
-d  指定要产生代码所在目录
-client 生成客户端测试web service的代码
-server 生成服务器启动web  service的代码
-impl 生成web service的实现代码
-ant  生成build.xml文件
-all 生成所有开始端点代码:types,service proxy,,service interface, server mainline, client mainline, implementation object, and an Ant build.xml file.
3、在执行完上面的命令后,就会发现在当前目录下多了个src目录拷贝整个文件夹放置工程目录下。 
4、在WebServiceImpl_WebServiceImplPort_Client文件中,修改入参调用即可,如:
 java.lang.String _setService_request =  "<?xml version=\"1.0\" encoding=\"UTF-8\"?><request  number=\"ID-0601-170922-0029\"   time=\"2019-02-22 09:15:34\"></request>";

五、其他说明

1、客户端主要依赖wsdl生成代码,若更换了服务端方式很可能会导致生成的WSDL也不一样,那么客户端需要重新适配。有个项目就是因为觉得axis2太厚重不利于整合,改用了JWS方式实现,但又希望客户对端不做同步修改,折腾了很久也没对接上。

2、Soap协议有1.1和1.2区分,通过soapUI发送,格式头部信息是不同。

soapenv为1.1

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://webservice">
   <soapenv:Header/>
   <soapenv:Body>
      <ser:setService>
         <!--Optional:-->
         <request><![CDATA[<?xml version="1.0" encoding="UTF-8"?><request  number="ID-0601-170922-0029"   time="2019-02-22 09:15:34"></request>]]></request>
      </ser:setService>
   </soapenv:Body>
</soapenv:Envelope>

soap则为1.2 

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:web="http://webservice">
   <soap:Header/>
   <soap:Body>
      <web:setService>
         <!--Optional:-->
         <request><![CDATA[<?xml version="1.0" encoding="UTF-8"?><request  number="ID-0601-170922-0029"   time="2017-09-22 09:15:34" ></request>]]></request>
      </web:setService>
   </soap:Body>
</soap:Envelope>

3、WSDL格式字段说明

参考:https://www.cnblogs.com/ZDPPU/p/5908043.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值