SOAPWeb 服务是否只支持“ POST”http 方法

我在一次采访中遇到了这个问题,所以您能否告诉我 SOAP Web 服务是否只支持“ POST”http 方法,还是有一些方法可以在服务器端接受其他方法?

95475 次浏览

我一直使用 POST,但是根据 W3C 标准,SOAP 同时支持 POST 和 GET 方法。

编辑: 经过一些研究,它似乎不完全正确,因为你可以看到 给你。使用 GET 是 理论上是的可能的,因为 POST 和 GET 是 HTTP 传输协议的方法,SOAP 可以通过 HTTP 使用。

但是如您所知,GET 在查询字符串中包含请求。SOAP 请求(XML 消息)通常过于复杂和冗长,无法包含在查询字符串中,因此几乎每个实现(例如 JAX-WS)都只支持 POST。

Thread 已经有三年的历史了,但是我认为仍然会有很多人给自己同样的问题,并且会在网上找到错误的答案。这个问题的答案是否定的,GET 方法也可以使用。

根据 SOAP 规范,可以在这里找到: “ a href = https://www.w3.org/TR/2007/REC-soap12-part0-20070427/# Transport”rel = “ norefrer”> https://www.w3.org/tr/2007/rec-soap12-part0-20070427/#transport GET 和 POST 方法都可以用于通过 http 交换 SOAP 消息。 在 HTTP 请求体中使用 HTTPPOST 方法传输 SOAP 消息使用一种称为 SOAP 请求-响应消息交换模式的模式。在 HTTPGET 的情况下,使用一种称为 SOAP 响应消息交换模式的模式。这两种模式的主要区别是:

第一种类型的交互允许使用 HTTP POST 主体中的数据来创建或修改由 HTTP 请求所指向的 URI 标识的资源的状态。第二种类型的交互模式提供了使用 HTTP GET 请求获取资源表示形式的能力,而无需以任何方式改变其状态。在第一种情况下,与 SOAP 相关的方面是 HTTP POST 请求的主体是 SOAP 消息,必须作为遵从 POST 语义所需的特定于应用程序的处理的一部分进行处理(根据 SOAP 处理模型)。在第二种情况下,可以预见的典型用法是将被请求的资源的表示形式作为 SOAP 消息而不是 HTML 或通用 XML 文档返回。也就是说,响应消息的 HTTP 内容类型头将其标识为媒体类型“ application/soap + xml”

因此,GET 和 POST 方法都可以使用。另一方面,在实践中大多采用 POST 方法。

糟糕的是,当比较 RESTful 服务和 SOAP 服务时,作为 REST 人员的一个优势,他们带来了缓存,而这在 SOAP 中是不可用的,因为 SOAP 只使用 POST。这是完全错误的。

这是 SOAP 中 GET 的一个实现:

@WebServiceProvider(targetNamespace="http://attachment.service.soap.com/download")
@ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
@BindingType(value = HTTPBinding.HTTP_BINDING)
public final class ImageDownloadServiceProvider implements Provider<DataSource> {
@Resource
private WebServiceContext wsContext;


@Override
public DataSource invoke(DataSource request) {
if (wsContext == null)
throw new RuntimeException("dependency injection failed on wsContext");
MessageContext msgContext = wsContext.getMessageContext();
HttpExchange exchange = (HttpExchange) msgContext.get("com.sun.xml.internal.ws.http.exchange");
String filename = exchange.getRequestURI().getQuery().replace("file=", "");
switch ((String) msgContext.get(MessageContext.HTTP_REQUEST_METHOD)) {
case "GET":
return doGet(filename);
default:
throw new HTTPException(405);
}
}


private DataSource doGet(String filename) {
FileDataSource fds = new FileDataSource(filename);
MimetypesFileTypeMap mtftm = new MimetypesFileTypeMap();
mtftm.addMimeTypes("image/jpeg jpg");
fds.setFileTypeMap(mtftm);
return fds;
}