如何使用java解析XOP / MTOM SOAP响应?

我只是想知道,有没有简单的方法来解析MTOM / XOP SOAP响应。 问题是我使用普通HTTP发送soap消息和javax.xml来解析响应。 但是有些服务用mulipart / related响应我,它需要更复杂的逻辑来解析它(性能很重要)。 所以我想我可以以某种方式利用apache cxf,apache axiom或任何其他库来解析MTOM / XOP SOAP响应吗?

这些unit testing向您展示如何使用CXF从MTOM消息中提取附件。 如果将来不存在此链接,我将内联其中一个测试:

private MessageImpl msg; @Before public void setUp() throws Exception { msg = new MessageImpl(); Exchange exchange = new ExchangeImpl(); msg.setExchange(exchange); } @Test public void testDeserializerMtom() throws Exception { InputStream is = getClass().getResourceAsStream("mimedata"); String ct = "multipart/related; type=\"application/xop+xml\"; " + "start=\"\"; " + "start-info=\"text/xml; charset=utf-8\"; " + "boundary=\"----=_Part_4_701508.1145579811786\""; msg.put(Message.CONTENT_TYPE, ct); msg.setContent(InputStream.class, is); AttachmentDeserializer deserializer = new AttachmentDeserializer(msg); deserializer.initializeAttachments(); InputStream attBody = msg.getContent(InputStream.class); assertTrue(attBody != is); assertTrue(attBody instanceof DelegatingInputStream); Collection atts = msg.getAttachments(); assertNotNull(atts); Iterator itr = atts.iterator(); assertTrue(itr.hasNext()); Attachment a = itr.next(); assertNotNull(a); InputStream attIs = a.getDataHandler().getInputStream(); // check the cached output stream ByteArrayOutputStream out = new ByteArrayOutputStream(); IOUtils.copy(attBody, out); assertTrue(out.toString().startsWith(" 

在您的情况下, ct将来自响应的内容类型标头。 "mimedata"将是回应的内容。

无需使用CXF ,标准的javax.mail.internet.MimeMultipart类可以完成这项工作,并且它非常易于使用(也可以创建MTOM请求)。

这是一个非常简单的示例,用于解码部分MTOM响应:

 MimeMultipart mp = new MimeMultipart(new ByteArrayDataSource(data, contentType)); int count = mp.getCount(); for (int i = 0; i < count; i++) { BodyPart bp = mp.getBodyPart(i); bp.saveFile(filepath + "_" + i); } 

我有同样的问题并解决了@Nicolas Albert

 public byte[] mimeParser(InputStream isMtm) { ByteArrayOutputStream baos = null; try { MimeMultipart mp = new MimeMultipart(new ByteArrayDataSource(isMtm, ct)); int count = mp.getCount(); baos = new ByteArrayOutputStream(); for (int i = 0; i < count; i++) { BodyPart bodyPart = mp.getBodyPart(i); if (!Part.ATTACHMENT .equalsIgnoreCase(bodyPart.getDisposition()) && !StringUtils.isNotBlank(bodyPart.getFileName())) { continue; // dealing with attachments only } bodyPart.writeTo(baos); } byte[] attachment = baos.toByteArray(); FileUtils.writeByteArrayToFile(new File("E:/wss/attachment.zip"), attachment); return attachment; } catch (Exception ex) { ex.printStackTrace(); } finally { if (baos != null) { try { baos.close(); } catch (Exception ex) { } } } return null; }