SwA上传失败主因是Content-Type配置错误:必须用multipart/related包装,主XML部分Content-Type须为text/xml或application/soap+xml,且start-info参数需显式指定,各part的Content-ID须含尖括号并严格匹配SOAP中cid引用。

SwA上传失败时常见的Content-Type错误
SwA不是普通XML POST,必须用multipart/related包装,且主XML部分的Content-Type必须是text/xml或application/soap+xml,不能是application/xml。常见错误是直接把SOAP XML当纯文本POST,导致服务端解析出Invalid MIME structure或Missing start-info parameter。
-
start-info参数必须显式指定,例如:Content-Type: multipart/related; type="text/xml"; start="<rootpart>"; boundary="uuid:12345"</rootpart> - 每个part需带
Content-ID头,格式为<xxx@yyy>(尖括号不可省略) - 附件part的
Content-Transfer-Encoding建议用base64,避免二进制乱码
Python中用requests构造SwA请求的关键步骤
标准requests.post()不支持原生SwA,需手动拼接multipart body。核心是控制boundary、start-info和各part的headers顺序。
import requests
soap_xml = '''<?xml version="1.0"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<UploadDocument xmlns="http://example.com/">
<attachmentId><cid:doc@swa.example></attachmentId>
</UploadDocument>
</soap:Body>
</soap:Envelope>'''
with open("report.pdf", "rb") as f:
pdf_data = f.read()
boundary = "uuid:abc123"
start = "<root@swa.example>"
body = (
f"--{boundary}\r\n"
'Content-Type: text/xml; charset=utf-8\r\n'
f'Content-Transfer-Encoding: 8bit\r\n'
f'Content-ID: {start}\r\n\r\n'
f"{soap_xml}\r\n"
f"--{boundary}\r\n"
'Content-Type: application/pdf\r\n'
'Content-Transfer-Encoding: base64\r\n'
'Content-ID: <doc@swa.example>\r\n\r\n'
+ base64.b64encode(pdf_data).decode() + "\r\n"
f"--{boundary}--\r\n"
)
headers = {
"Content-Type": f'multipart/related; type="text/xml"; start="{start}"; boundary="{boundary}"',
"SOAPAction": '"http://example.com/UploadDocument"'
}
response = requests.post("https://api.example.com/soap", headers=headers, data=body)
Java(Apache Axis2)里AttachmentUtils的典型误用
Axis2自带org.apache.axis2.attachments.Attachments,但很多人直接传入FileDataSource而忽略Content-ID一致性。关键点在于:SOAP body中引用的cid:必须与附件part的Content-ID完全匹配(包括大小写和空格)。
- 不要用
new DataHandler(new FileDataSource("x.pdf"))后直接addAttachment()——它会自动生成随机Content-ID,无法与SOAP中硬编码的<cid:xxx>对齐 - 正确做法是先创建
javax.activation.DataHandler,再调用setContentType("application/pdf")和setContentID("<doc@swa.example>") - Axis2默认启用SwA,但若服务端返回
HTTP 415 Unsupported Media Type,检查是否启用了messageBuilder配置:application/soap+xml对应org.apache.axis2.builder.SOAPBuilder
调试SwA请求时必须检查的三个原始响应头
服务端拒绝SwA请求时,HTTP状态码往往掩盖了真实问题。真正线索藏在响应头里:
-
Content-Type是否返回multipart/related?如果不是,说明服务端未识别SwA,可能因start-info缺失或boundary不匹配 -
X-SOAP-Error(某些厂商自定义头)常含Invalid attachment reference: cid:xxx,意味着SOAP body里的cid:没在附件part中找到对应Content-ID -
Connection为close且无Content-Length,大概率是multipart body末尾少了一个--{boundary}--,导致服务端等待更多数据超时
SwA的麻烦不在逻辑,而在每个header字段的字面精确性——少一个尖括号、多一个空格、大小写错位,都会让整个请求静默失败。










