SOAP UI Java中多XML附件添加失败:找不到file1.xml附件求助
看起来你在给Java SOAP服务发送多附件请求时踩了个常见的坑——服务端只识别到了最后一个附件,完全找不到file1.xml。从错误信息No attachment for id file1.xml found in [file2.xml]能看出来,服务端的附件列表里只有file2.xml,要么是客户端没把第一个附件发出去,要么是CID关联逻辑出了问题。下面分几个方向帮你排查:
1. 附件的Content-ID与请求中的CID不匹配
SOAP请求里用cid:file1.xml引用附件,对应的附件必须在MIME头部设置标准格式的Content-ID:
- 附件的Content-ID需要写成
<file1.xml>(带尖括号),而请求里的引用是cid:file1.xml(去掉尖括号),这是RFC 2392规定的标准格式。 - 很多开发者会在这里出错:要么附件的Content-ID没加尖括号,要么请求里的CID多了尖括号,导致服务端无法关联附件和引用。
2. 客户端添加附件时覆盖了前一个
如果你用JAX-WS客户端(比如CXF、Metro),要确保所有附件都被加入同一个列表,而不是用put方法单独设置(后面的附件会直接覆盖前面的)。举个CXF的正确示例:
// 获取服务端代理 Client client = ClientProxy.getClient(yourServicePort); // 创建第一个附件并设置正确的Content-ID Attachment att1 = new AttachmentImpl("file1", new DataHandler(new FileDataSource("file1.xml"))); att1.setContentId("<file1.xml>"); // 创建第二个附件 Attachment att2 = new AttachmentImpl("file2", new DataHandler(new FileDataSource("file2.xml"))); att2.setContentId("<file2.xml>"); // 将两个附件加入列表后,再放入请求上下文 List<Attachment> attachments = new ArrayList<>(); attachments.add(att1); attachments.add(att2); client.getRequestContext().put(AttachmentOutgoingMessageInterceptor.WS_ATTACHMENTS, attachments);
如果之前你是分别调用put设置单个附件,那最后一个附件会覆盖前面的,自然服务端只收到file2.xml。
3. MIME消息的结构不符合规范
SOAP带附件的请求必须是multipart/related类型的MIME消息,结构顺序要严格遵循:
- 第一部分是SOAP信封本身,类型为
text/xml - 后续依次是每个附件,每个附件都要有独立的边界、Content-Type和Content-ID
你可以用抓包工具(比如Wireshark、Postman)查看实际发送的请求,确认两个附件都被包含在MIME消息里,且每个附件的Content-ID都正确。正确的MIME结构大致如下:
Content-Type: multipart/related; boundary="----=_Part_0_123456789.0123456"; type="text/xml" ------=_Part_0_123456789.0123456 Content-Type: text/xml; charset=UTF-8 Content-Transfer-Encoding: 8bit <!-- 你的SOAP信封内容 --> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" ...> ... </soapenv:Envelope> ------=_Part_0_123456789.0123456 Content-Type: application/xml Content-ID: <file1.xml> Content-Transfer-Encoding: binary <!-- file1.xml的内容 --> ------=_Part_0_123456789.0123456 Content-Type: application/xml Content-ID: <file2.xml> Content-Transfer-Encoding: binary <!-- file2.xml的内容 --> ------=_Part_0_123456789.0123456--
4. 服务端解析逻辑存在问题
如果前面的检查都没问题,那可以在服务端加一段调试代码,看看实际收到的附件列表:
@WebMethod public void import(RequestMessage request) { MessageContext context = WebServiceContext.getMessageContext(); Iterator<Attachment> attIterator = context.getAttachments(); while (attIterator.hasNext()) { Attachment att = attIterator.next(); System.out.println("收到附件:" + att.getContentId()); } }
如果这里只打印出file2.xml,说明客户端确实没发送第一个附件,回到客户端排查;如果两个附件都能打印出来,那说明服务端的CID匹配逻辑有问题(比如没处理尖括号、大小写敏感)。
优先从Content-ID匹配和客户端添加附件的方式入手排查,这两个是最常见的问题根源。
内容的提问来源于stack exchange,提问作者Bambus

