欢迎使用普元产品知识库,本知识库包含普元应用开发平台EOSPlatform,流程平台BPS,企业服务总线ESB,微服务平台Microservice,运维管理平台Devops,数据集成平台DI

页面树结构

欢迎使用普元文档库

Skip to end of metadata
Go to start of metadata

在项目实施的过程中,遇到最普遍的问题之一就是,第三方系统调用ESB时自定义参数无法识别的问题。本文主要对ESB的参数进行介绍,以及一些参数识别无效的处理方法。
首先来研究一下这几个参数是干嘛的。
ClientId直面意思是客户端id,它的含义就是指接口调用方的身份标识。它的组成成分包含,应用编码前缀、系统域、应用编码后缀。
例如com.zhaojin.esb.ZJKY.BPM中的com.zhaojin.esb 应用编码前缀,ZJKY是系统域,BPM是应用编码后缀。
OperationCode直面意思是操作码,由应用编码前缀、系统域、应用编码后缀、ESB服务名、ESB操作名组成。它是直指提供方接口的具体实现方法的声明。
例如com.zhaojin.esb.ZJKY.CONTRACT.ContractInfo_Update.Update_info中的 com.zhaojin.esb 应用编码前缀,ZJKY是系统域,BPM是应用编码后缀,ContractInfo_Update是ESB服务名,Update_info 是ESB操作名。一般来说,ESB服务名所指提供方接口名,ESB操作名所指提供方接口中某一方法名。
了解以上,我们来说说如何提供制定两个参数规则。比如当前有两个系统需要接入ESB,一个是BPM,一个是合同管理系统。由BPM系统发请求给合同完成某一流程更新合同的操作。调用发起方是BPM,接收方是合同管理系统。那么按照以上所说的参数作用,ClientId 就是com.zhaojin.esb.ZJKY.BPM,而OperationCode就是com.zhaojin.esb.ZJKY.CONTRACT.ContractInfo_Update.Update_info。这两个参数就是要在BPM系统向ESB发起请求时必填的参数。
     ESB中要求参数从http request header中添加,可以直接对其解析。解析后根据ESB-SAM系统的配置规则对其请求发起具体业务服务。
     这里以java cfx方式调用为例

//接入ESB地址    
String endpoint = "http://127.0.0.1:9090/com.zhaojin.esb.ZJKY.CONTRACT.ContractInfo_Update.Update_info ";
WebClient client = WebClient.create(endpoint);
//添加ClientId
client.header("ClientId", "com.zhaojin.esb.ZJKY.BPM");
//添加OperationCode
client.header("OperationCode", "com.zhaojin.esb.ZJKY.CONTRACT.ContractInfo_Update.Update_info");
//调用方式1
//InvokeMethodService invokeMethod = JAXRSClientFactory.fromClient(client, InvokeMethodService.class);
//调用方式2
   InvokeMethodService invokeMethod = JAXRSClientFactory.fromClient(client, InvokeMethodService.class, true);
//params是具体的业务数据
   String res = invokeMethod.otherInvoke(params);


这里有几个重点关注的地方。也是项目中所遇到的一个真实例子。调用方在一开始发起调用的时候所使用的是调用方式1,代码检查都没有问题,但始终在ESB这边接收不到ClientId和OperationCode。后来,在厂商尝试无果的情况下,我们把它的调用代码拿过来逐个排查,发现是由于这个接口函数重载了多个同名方法。通过查询相关的API文档,确定了采用调用方式2的方式,最终将ESB必须的两个参数传了过来。
另外,在非java语言中,Asp发起调用ESB请求的时候,也遇到了一个特别诡异的传参问题。

Set xmlhttp = server.CreateObject("MSXML2.XMLHTTP")
xmlhttp.Open "POST",url,False
xmlhttp.setRequestHeader "ClientId","com.zhaojin.esb.ZJKY.BPM"
xmlhttp.setRequestHeader "OperationCode","com.zhaojin.esb.ZJKY.CONTRACT.ContractInfo_Update.Update_info" 
...


检查代码都没有问题,但是确实就是ESB这边接收不到参数,通过抓包工具发现发起调用的数据包中的两个参数key ClientId和OperationCode变成了clientid和operationcode所致。排查后,发现是MSXML2.XMLHTTP组件传递的过程中自己做了一次转换。后来替换了组件为CreateObject("MSXML2.ServerXMLHTTP")解决了这个问题,当然了这其中还有其他的一些问题。但最终通过替换上述组件完美解决了一系列问题。
这里也给咱们ESB产品提一个建议,在识别参数这里忽略大小写,因为这个header参数是ESB产品自定义的,考虑到第三方接入兼容性的问题,希望这里可以完善一下。
另外我们再说说某些平台的限制,有一些平台无法在request header中加入自定义参数。通过查询ESB文档,其实在soap报文中做了一些处理,可以通过soap header中加入如上两个参数。具体配置,在Transport上添加拦截器
com.primeton.esb.governance.interceptor.parameter.ParameterInterceptor

<soapenv:Header>
   <ClientId>
      com.zhaojin.esb.ZJKY.BPM
   </ClientId>
   <OperationCode>
      com.zhaojin.esb.ZJKY.CONTRACT.ContractInfo_Update.Update_info
   </OperationCode>
< /soapenv:Header>


这里要注意的是,第三方平台在追加soap header中的参数时,可能会遇到ESB无法识别的情况。排查发现有的第三方系统发起调用时在具体参数中增加命名空间,比如<s:ClientId>,这样我们的产品默认的拦截器其实是不能对其进行正确的解析的。有两个解决办法,一是在调用发起方对soap header进行改造,去掉相应的命名空间,另外就是重写拦截器,去适配第三方的报文格式。重写拦截器的方法,更能适应第三方系统各种复杂的header报文格式。建议谨慎使用,避免第三方实施厂家各种重度依赖ESB,从而给自己增加额外的不必要的工作量。

  • 无标签