SOAP 客户端真的需要使用 WSDL 吗?
Does a SOAP client really need to use a WSDL?
我见过 SOAP 客户端的例子,它们只是像这样发送一个 XML SOAP 信封的负载作为 HTTP 请求主体....
String payload="""
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
Some soap crapola
</soapenv:Body>
</soapenv:Envelope>
"""
HttpPost httpPost = new HttpPost("somecraapysoapwebsevice.com/biteme");
StringEntity entity = new StringEntity(payload);
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "text/xml");
httpPost.setHeader("Content-type", "text/xml");
HttpResponse response = httpclient.execute(httpPost);
此代码不会影响 WSDL。这种方法会不会有什么问题?
此外,如果我使用 WSDL 生成 Java 类 并以这种方式发送请求,服务器是否会认为传入的信息与我上面所做的有任何不同?
SOAP 主要用于具有数百个 SOAP 服务的企业环境,并且需要自动生成客户端存根。
考虑到 nullable/non-nullable 字段、复杂字段、集合等所有限制,使用所有 DTO 对象从给定的 WSDL 生成客户端存根更简单。
当合约可能包含数十个不同类型的字段并且其中许多是集合或具有自己字段的复杂类型时,您将如何为 CreateContract 请求手动构建信封?
当您需要将正文转换为 POJO
时,与返回的响应 GetContract 相同
如果您只需要使用单个参数调用单个方法,您可能会发现使用参数占位符对 soap 信封进行硬编码会更简单。由你决定。
WSDL 只是客户端和服务器之间的契约。对于服务器来说,请求主体是如何组成的并不重要,是手工编写还是使用自动生成的代码。如果请求符合合同服务器应该接受它。
您始终可以检查您手工制作的请求是否与 WSDL 一致,并使用 SoapUI
等工具对其进行测试
像这样创建 SOAP 请求没有固有问题,但存在一些缺陷:
- 如果您正在调用的服务的 schema/wsdl 发生变化,您必须在创建 SOAP 请求的代码中反映出来。如果您使用 WSDL,您只需要 re-run 您的 data-binder 使用更新 WSDL/schema.
- 使用字符串创建和解析 XML 不是一个好主意。您应该使用 DOM,并在将其发送到您的 HTTP/SOAP 请求之前对其进行序列化。
SOAP 服务看不到使用 WSDL/data-binding 的客户端与以其他方式创建 SOAP 请求的代码之间的任何区别。只要您的请求与请求模式匹配,并且您设置了 SOAP-Action HTTP header,您应该没问题。
在某些情况下,不使用 WSDL 是一个很好的论据,其中您的组件是一个消息代理(例如中间件),需要接收和转发不同消息类型的负载,其中一些您甚至可能没有
的 WSDL 定义
我见过 SOAP 客户端的例子,它们只是像这样发送一个 XML SOAP 信封的负载作为 HTTP 请求主体....
String payload="""
<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
Some soap crapola
</soapenv:Body>
</soapenv:Envelope>
"""
HttpPost httpPost = new HttpPost("somecraapysoapwebsevice.com/biteme");
StringEntity entity = new StringEntity(payload);
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "text/xml");
httpPost.setHeader("Content-type", "text/xml");
HttpResponse response = httpclient.execute(httpPost);
此代码不会影响 WSDL。这种方法会不会有什么问题?
此外,如果我使用 WSDL 生成 Java 类 并以这种方式发送请求,服务器是否会认为传入的信息与我上面所做的有任何不同?
SOAP 主要用于具有数百个 SOAP 服务的企业环境,并且需要自动生成客户端存根。
考虑到 nullable/non-nullable 字段、复杂字段、集合等所有限制,使用所有 DTO 对象从给定的 WSDL 生成客户端存根更简单。
当合约可能包含数十个不同类型的字段并且其中许多是集合或具有自己字段的复杂类型时,您将如何为 CreateContract 请求手动构建信封? 当您需要将正文转换为 POJO
时,与返回的响应 GetContract 相同如果您只需要使用单个参数调用单个方法,您可能会发现使用参数占位符对 soap 信封进行硬编码会更简单。由你决定。
WSDL 只是客户端和服务器之间的契约。对于服务器来说,请求主体是如何组成的并不重要,是手工编写还是使用自动生成的代码。如果请求符合合同服务器应该接受它。
您始终可以检查您手工制作的请求是否与 WSDL 一致,并使用 SoapUI
等工具对其进行测试像这样创建 SOAP 请求没有固有问题,但存在一些缺陷:
- 如果您正在调用的服务的 schema/wsdl 发生变化,您必须在创建 SOAP 请求的代码中反映出来。如果您使用 WSDL,您只需要 re-run 您的 data-binder 使用更新 WSDL/schema.
- 使用字符串创建和解析 XML 不是一个好主意。您应该使用 DOM,并在将其发送到您的 HTTP/SOAP 请求之前对其进行序列化。
SOAP 服务看不到使用 WSDL/data-binding 的客户端与以其他方式创建 SOAP 请求的代码之间的任何区别。只要您的请求与请求模式匹配,并且您设置了 SOAP-Action HTTP header,您应该没问题。
在某些情况下,不使用 WSDL 是一个很好的论据,其中您的组件是一个消息代理(例如中间件),需要接收和转发不同消息类型的负载,其中一些您甚至可能没有
的 WSDL 定义