技术文章

当前位置:首页>帮助手册>技术文章

O2server 调用外部webservice(jaxws)服务

时间:2022-04-22   
内容导读

本篇聚焦O2OA 平台调用外部网络服务时的报文约定与排障,先解释描述文档中消息样式与序列化方式的差异,以及注解里如何声明相应取值。若走脚本内建通道出现上下文构建失败,多与类加载顺序导致绑定库不可见有关,属于后续版本待修的问题。改为直接发起请求、自行拼装信封内容的做法可绕开该限制,报文结构与目标地址仍须按对方服务严格核对,返回内容的解析也宜先用样例验证。

WSDL 概述

WSDL 文档(WSDL = Web 服务描述语言)描述了 Web 服务。WSDL 绑定描述服务如何绑定到消息传递协议,尤其是 SOAP 消息传递协议。WSDL SOAP 绑定可以是 (RPC)远程过程调用样式或 (DOCUMENT)文档样式,也可以具有 (ENCODED)编码用途或 (LITERAL)文本用途,由此形成四种样式/使用模型:

WSDL 区分文档和 RPC 两种消息样式,消息样式会影响 SOAP Body 的内容:

对于通过序列化/反序列化抽象出数据线格式的应用程序,还需选择序列化格式。常见的序列化格式有两种:

在 Java 编码中,可通过 @SOAPBinding(style = Style.RPC, use = Use.LITERAL) 设置 style 和 use。

WSDL 样例

RPC/ENCODED 样例

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://jaxws.rooo000.net/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://jaxws.rooo000.net/" name="Hello3Service">
  <types/>
  <message name="say3">
    <part name="arg0" type="xsd:string"/>
  </message>
  <message name="say3Response">
    <part name="return" type="xsd:string"/>
  </message>
  <portType name="Hello3">
    <operation name="say3">
      <input wsam:Action="http://jaxws.rooo000.net/Hello3/say3Request" message="tns:say3"/>
      <output wsam:Action="http://jaxws.rooo000.net/Hello3/say3Response" message="tns:say3Response"/>
    </operation>
  </portType>
  <binding name="Hello3PortBinding" type="tns:Hello3">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
    <operation name="say3">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal" namespace="http://jaxws.rooo000.net/"/>
      </input>
      <output>
        <soap:body use="literal" namespace="http://jaxws.rooo000.net/"/>
      </output>
    </operation>
  </binding>
  <service name="Hello3Service">
    <port name="Hello3Port" binding="tns:Hello3PortBinding">
      <soap:address location="http://127.0.0.1:8080/jaxws/hello3"/>
    </port>
  </service>
</definitions>

RPC/LITERAL 样例

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://jaxws.rooo000.net/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://jaxws.rooo000.net/" name="Hello4Service">
  <types/>
  <message name="say4">
    <part name="arg0" type="xsd:string"/>
  </message>
  <message name="say4Response">
    <part name="return" type="xsd:string"/>
  </message>
  <portType name="hello4">
    <operation name="say4">
      <input wsam:Action="http://jaxws.rooo000.net/hello4/say4Request" message="tns:say4"/>
      <output wsam:Action="http://jaxws.rooo000.net/hello4/say4Response" message="tns:say4Response"/>
    </operation>
  </portType>
  <binding name="hello4PortBinding" type="tns:hello4">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
    <operation name="say4">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal" namespace="http://jaxws.rooo000.net/"/>
      </input>
      <output>
        <soap:body use="literal" namespace="http://jaxws.rooo000.net/"/>
      </output>
    </operation>
  </binding>
  <service name="Hello4Service">
    <port name="hello4Port" binding="tns:hello4PortBinding">
      <soap:address location="http://127.0.0.1:8080/jaxws/hello4"/>
    </port>
  </service>
</definitions>

DOCUMENT/ENCODED 样例

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://jaxws.rooo000.net/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://jaxws.rooo000.net/" name="Hello1Service">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://jaxws.rooo000.net/" schemaLocation="http://127.0.0.1:8080/jaxws/hello1?xsd=1"/>
    </xsd:schema>
  </types>
  <message name="say1">
    <part name="parameters" element="tns:say1"/>
  </message>
  <message name="say1Response">
    <part name="parameters" element="tns:say1Response"/>
  </message>
  <portType name="Hello1">
    <operation name="say1">
      <input wsam:Action="http://jaxws.rooo000.net/Hello1/say1Request" message="tns:say1"/>
      <output wsam:Action="http://jaxws.rooo000.net/Hello1/say1Response" message="tns:say1Response"/>
    </operation>
  </portType>
  <binding name="Hello1PortBinding" type="tns:Hello1">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="say1">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="Hello1Service">
    <port name="Hello1Port" binding="tns:Hello1PortBinding">
      <soap:address location="http://127.0.0.1:8080/jaxws/hello1"/>
    </port>
  </service>
</definitions>

DOCUMENT/LITERAL 样例

<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://jaxws.rooo000.net/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://jaxws.rooo000.net/" name="Hello2Service">
  <types>
    <xsd:schema>
      <xsd:import namespace="http://jaxws.rooo000.net/" schemaLocation="http://127.0.0.1:8080/jaxws/hello2?xsd=1"/>
    </xsd:schema>
  </types>
  <message name="say2">
    <part name="parameters" element="tns:say2"/>
  </message>
  <message name="say2Response">
    <part name="parameters" element="tns:say2Response"/>
  </message>
  <portType name="Hello2">
    <operation name="say2">
      <input wsam:Action="http://jaxws.rooo000.net/Hello2/say2Request" message="tns:say2"/>
      <output wsam:Action="http://jaxws.rooo000.net/Hello2/say2Response" message="tns:say2Response"/>
    </operation>
  </portType>
  <binding name="Hello2PortBinding" type="tns:Hello2">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="say2">
      <soap:operation soapAction=""/>
      <input>
        <soap:body use="literal"/>
      </input>
      <output>
        <soap:body use="literal"/>
      </output>
    </operation>
  </binding>
  <service name="Hello2Service">
    <port name="Hello2Port" binding="tns:Hello2PortBinding">
      <soap:address location="http://127.0.0.1:8080/jaxws/hello2"/>
    </port>
  </service>
</definitions>

调用 jaxws 服务

默认调用

脚本中封装了 webserviceClient 对象,用于进行 jaxws 调用。

var url_1 = 'http://127.0.0.1:8080/jaxws/hello1?wsdl';
var url_2 = 'http://127.0.0.1:8080/jaxws/hello2?wsdl';
var url_3 = 'http://127.0.0.1:8080/jaxws/hello3?wsdl';
var url_4 = 'http://127.0.0.1:8080/jaxws/hello4?wsdl';

var o1 = this.service.soap(url_1, 'say1', 'o2oa');
print('hello1:' + o1[0]);
var o2 = this.service.soap(url_2, 'say2', 'o2oa');
print('hello2:' + o2[0]);
var o3 = this.service.soap(url_3, 'say3', 'o2oa');
print('hello3:' + o3[0]);
var o4 = this.service.soap(url_4, 'say4', 'o2oa');
print('hello4:' + o4[0]);

测试表明,脚本的 soap 可以正常调用 RPC 样式的服务,但调用 document 样式的服务会失败。

计算错误: Unable to create JAXBContext for generated packages: "net.rooo000.jaxws" 不包含 ObjectFactory.class 或 jaxb.index

这是因为 WebAppClassLoader 需要通过父 classLoader 才能 loader 到 jakarta.xml.bind-api,后续版本将修复此问题。

com.x.program.center.jaxrs.agent.ExceptionAgentEval: 代理 id:ccdd72cf-8e14-487d-89f3-53f9c32d7c9a, 名称:jaxws调用测试, 别名:, 计算错误: Unable to create JAXBContext for generated packages: "net.rooo000.jaxws" 不包含 ObjectFactory.class 或 jaxb.index, 脚本:/********************
API Document: http://127.0.0.1/api
********************/

var url_1 = 'http://127.0.0.1:8080/jaxws/hello1?wsdl';
var url_2 = 'http://127.0.0.1:8080/jaxws/hello2?wsdl';
var url_3 = 'http://127.0.0.1:8080/jaxws/hello3?wsdl';
var url_4 = 'http://127.0.0.1:8080/jaxws/hello4?wsdl';

// var o1 = this.service.soap(url_1, 'say1', 'o2oa');
// print('hello1:' + o1[0]);
// var o2 = this.service.soap(url_2, 'say2', 'o2oa');
// print('hello2:' + o2[0]);
// var o3 = this.service.soap(url_3, 'say3', 'o2oa');
// print('hello3:' + o3[0]);
var o4 = this.service.soap(url_4, 'say4', 'o2oa');
print('hello4:' + o4[0]);
.
	at com.x.program.center.jaxrs.agent.ActionExecute.execute(ActionExecute.java:83) ~[classes/:?]
	at com.x.program.center.jaxrs.agent.AgentAction.execute(AgentAction.java:192) ~[classes/:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?]
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
	at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
	at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52) ~[jaxrs-ri-2.35.jar:2.35.]
......

目前 o2server 仅支持 RPC 样式的调用,尚不支持 DOCUMENT 样式;7.1.0 以后的版本将支持 Document 样式调用。

直接通过 HTTP POST 调用

此场景下可直接发送 http 请求传输数据,完成 soap 请求。

/********************
API Document: http://127.0.0.1/api
********************/

var text = encodeURIComponent('<result><plmid>001</plmid><type>reject</type><message>下一步</message></result>');
var url = 'http://192.168.1.100/Service/OA.asmx/Hello';

var HttpConnection = Java.type('com.x.base.core.project.connection.HttpConnection');
var ArrayList = Java.type("java.util.ArrayList");
var NameValuePair = Java.type("com.x.base.core.project.bean.NameValuePair");

var heads = new ArrayList();
heads.add(new NameValuePair('Content-Type', 'application/x-www-form-urlencoded'));

var o = HttpConnection.postAsString(url, heads, "strRetXML=" + text, 300, 300);
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!result start')
print(o)
print('!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!result end')

直接发送 soap 消息体调用 jaxws 服务

特殊情况下可以使用拼装好的 xml 格式 soap 消息体调用服务。

var soap11 ='<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><RollBackProcess2 xmlns="http://tempuri.org/"><strRetXML>string</strRetXML></RollBackProcess2></soap:Body></soap:Envelope>'

var o = this.service.jaxwsXml('http://10.0.10.24/PLMService/OAProcess.asmx',soap11);

print('!!!!!!!!!!!!!!!!!!!!!!!call jaxwsXml start');
print(o[0])
print('!!!!!!!!!!!!!!!!!!!!!!!call jaxwsXml end');

相关问题讨论

windows 环境下启动失败 Exception: can not define o2server base directory.

计算错误: Unable to create JAXBContext for generated packages: "net.rooo000.jaxws" 不包含 ObjectFactory.class 或 jaxb.index

查看原帖讨论 · 12,273 次浏览

自定义组件部署到 webServer 目录下,过一会儿文件夹 jiu'xiao'sh...

这是由于 WebAppClassLoader 在父 classLoader 才能 loader 到 jakarta.xml.bind-api 导致的,后续版本将修复此问题.

查看原帖讨论 · 30,419 次浏览

关于运行 o2server 报 NoClassDefFoundError: org/apache/logging/log4j/core/Layout 的问题

计算错误: Unable to create JAXBContext for generated packages: "net.rooo000.jaxws" 不包含 ObjectFactory.class 或 jaxb.index

查看原帖讨论 · 11,173 次浏览

相关内容

O2OA 翱途 企业应用开发平台

兰德网络O2OA平台软件

开源、自主可控的协同办公底座

研发与运营

纵横翱途(杭州)科技有限公司

企业级协同应用 · 工作流引擎 · AI 智能体

www.o2oa.net | 400-888-0545

上一篇:平台维护-流转中工作数据的查询、操作和管理

下一篇:o2server 消息和消息处理器使用,如何将消息推送到webSocket 推送消息 日历消息 自建表 welink 钉钉 企业微信 公众号 邮件 mq restful jdbc hadoop或自建消