转载

WebService传奇故事 这是.Net、Java、C++语言的大战, 也是微软 与 IBM等厂商的PK,于是小白爬坑之路...

WebService传奇故事 这是.Net、Java、C++语言的大战, 也是微软 与 IBM等厂商的PK,于是小白爬坑之路...
WebService实战经验分享

说到WebSerivce,会想到很久很久前的SOAP,第一次看到的时候,觉得就一个神马。在.Net环境下使用过,导入WebService,直接使用,似乎也是很实用的一种跨平台跨系统的操作体验。单纯在.net体系,是感受不到WebService的阵痛,在java下,才是WebService爬坑的最佳土壤。这个故事的主题在于java与.net两个平台实现的差异,在于厂商实现的异常。

一、.Net vs Java

相比较于java,.net体系下的WebService,选择更单一,用ms的就好,直接用ide导入webservice。玩java的话,axis1,axis2,ide导入,wsimport命令生成,还有wsdl2java命令。

二、厂商之争

就实战经验来看,不同的厂商对soap的实现,还有差异。.net发起的soap报文是<soap>开头,而java发起soap发起了soap:env报文。导致跨平台调用的时候出现问题。

方案一 ide导入

直接使用eclipse导入WebService,同样的方式导入,STS却导入不了。所以实操过程中,选择eclipse导入。针对java平台的WebService调用,调用正常。但是调用一个神秘的WebService,一直报soap报文格式不对。如果没有记错的话,当时eclipse导入WebService,生成的是axis1的实现。网查axis1对于soap请求头处理,就是一个Bug。所以方案一,被丢掉了。

方案二 前辈方案+axis2

想着axis1搞不了的事情,兴许axis2能做。当被告之有方案借鉴时,感觉看到了希望。不过,没有看到操作手册,也不知道代码是怎么生成的。从包引用上来讲,用的是axis2,这个就是为什么有axis2方案尝试的原因了。也是迷惑人的地方。因为引入的包,压根没有使用到。但是从代理类的生成风格上来讲,还是具备排版精良的影响。使用axis2的代理类生成工具,生成完代理类之后,吓死了,感觉生成的代码就是一团芝麻糊,于是,直接丢掉了。为什么别人生成的axis2代理类这么优秀,而我生成的惨不忍睹?

方案三 wsimport方案

绕了半圈,回到了java sdk自带的wsimport,直接在命令行输入wsimport,会有提示。存放代理类的文件夹不存在的话,还不给生成,这个有点小小的坑。

WebService传奇故事 这是.Net、Java、C++语言的大战, 也是微软 与 IBM等厂商的PK,于是小白爬坑之路...
wsimport command

 

D:/>wsimport

缺少 WSDL_URI

用法: wsimport [options] <WSDL_URI>

/其中 [options] 包括:

-b <path> 指定 jaxws/jaxb 绑定文件或附加模式

(每个 <path> 都必须具有自己的 -b)

-B<jaxbOption> 将此选项传递给 JAXB 模式编译器

-catalog <file> 指定用于解析外部实体引用的目录文件

支持 TR9401, XCatalog 和 OASIS XML 目录格式。

-d <directory> 指定放置生成的输出文件的位置

-encoding <encoding> 指定源文件所使用的字符编码

-extension 允许供应商扩展 - 不按规范

指定功能。使用扩展可能会

导致应用程序不可移植或

无法与其他实现进行互操作

-help 显示帮助

-httpproxy:<host>:<port> 指定 HTTP 代理服务器 (端口默认为 8080)

-keep 保留生成的文件

-p <pkg> 指定目标程序包

-quiet 隐藏 wsimport 输出

-s <directory> 指定放置生成的源文件的位置

-target <version> 按给定的 JAXWS 规范版本生成代码

默认为 2.2, 接受的值为 2.0, 2.1 和 2.2

例如, 2.0 将为 JAXWS 2.0 规范生成兼容的代码

-verbose 有关编译器在执行什么操作的输出消息

-version 输出版本信息

-wsdllocation <location> @WebServiceClient.wsdlLocation 值

-clientjar <jarfile> 创建生成的 Artifact 的 jar 文件以及

调用 Web 服务所需的 WSDL 元数据。

-generateJWS 生成存根 JWS 实现文件

-implDestDir <directory> 指定生成 JWS 实现文件的位置

-implServiceName <name> 生成的 JWS 实现的服务名的本地部分

-implPortName <name> 生成的 JWS 实现的端口名的本地部分

/扩展:

-XadditionalHeaders 映射标头不绑定到请求或响应消息不绑定到

Java 方法参数

-Xauthfile 用于传送以下格式的授权信息的文件:

http://username:[email protected]/stock?wsdl

-Xdebug 输出调试信息

-Xno-addressing-databinding 允许 W3C EndpointReferenceType 到 Java 的绑定

-Xnocompile 不编译生成的 Java 文件

-XdisableAuthenticator 禁用由 JAX-WS RI 使用的验证程序,

将忽略 -Xauthfile 选项 (如果设置)

-XdisableSSLHostnameVerification 在提取 wsdl 时禁用 SSL 主机名

验证

/示例:

wsimport stock.wsdl -b stock.xml -b stock.xjb

wsimport -d generated http://example.org/stock?wsdl

照着命令行的提示来,就能生成代理类了。

采用wsimport生成的代理类竟然跟4年前同事留下的对接项目代码是一样的,于是修改soap:env就有着落了。实战证明,前辈们留下的代码管用。关键的代码就是自己实现一个报文处理的Handler,然后在Soap代理类调用时,先设置Handler!


 

wsInstance = new WS();

wsInstance.setHandlerResolver(portInfo -> {

List<Handler> handlerList = new ArrayList<>();

handlerList.add(new SOAPEnvelopeHandler());

return handlerList;

});

关注本公众号,输入soap获得SOAPEnvelopeHandler详细讲解。

方案不足之处

采用wsimport生成的代理类指定了wsdl位置,这个看起来怪怪,但是这种方案能修改soap请求报文,可以默认接受了这个让人心头有点痒痒的方案。

WebService优化

采用单例优先代练类的创建,能提升压测值。在未使用单例优化时,空接口也无法通过5000/min压测,采用单例优化后,可以通过。最终的优化方案为:

  1. 能缓存的,使用redis缓存60秒。过压测。
  2. 不能缓存的,过不了压测,限制每分钟调用频率。

受控环境下的WebService联调技术

如果开发机器不能直接调用对方的WebService,如何进行快速联调呢?关注本公众号,回复信息wsdebug,获取实战经验分享。

WebService与区服切换

回复信息switcharea,获取实战经验分享。

思考

今天的思考题:sonarqube报很多漏洞很多bug的代码是不是好代码?请留下您的思考答案。

结束语

WebService从诞生到现在,越来越不受待见了,越来越多的人喜欢采用更轻量级的WebAPI来代替WebService,采用JSON,采用更加透明的跨平台方案。但是WebService并没有死,因为生成代码还是一个优点。如果再次在java平台下对接WebService,请优先考虑jdk自带的wsimport进行代理类生成,可通过自定义SOAPHandler达到更好的兼容性。如有更好的方法,请留言告之。

关注公众号 看同行经验分享

WebService传奇故事 这是.Net、Java、C++语言的大战, 也是微软 与 IBM等厂商的PK,于是小白爬坑之路...
技术岛公众号
原文  http://www.jishudao.com/2019/07/23/webservice_legend/
正文到此结束
Loading...