How to parse XOP/MTOM SOAP response using java?

前端 未结 3 897
遇见更好的自我
遇见更好的自我 2020-12-06 18:26

I just want to know, is there any simple way for parsing MTOM/XOP SOAP response. The problem is that I use plain HTTP to send soap message and javax.xml for parsing respon

相关标签:
3条回答
  • 2020-12-06 18:46

    No need to use CXF, the standard javax.mail.internet.MimeMultipart class do the job and it's very easy to use (also to create MTOM request).

    Here a very simple sample to decode parts of a MTOM response:

    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);
    }
    
    0 讨论(0)
  • These unit tests show you how to use CXF to extract attachments out of an MTOM message. I'll inline one of the tests in case this link doesn't exist in the future:

    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=\"<soap.xml@xfire.codehaus.org>\"; "
                    + "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<Attachment> atts = msg.getAttachments();
        assertNotNull(atts);
    
        Iterator<Attachment> 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("<env:Envelope"));
    
        // try streaming a character off the wire
        assertTrue(attIs.read() == '/');
        assertTrue(attIs.read() == '9');
    }
    

    In your case, the ct will come from the content type header of the response. The "mimedata" will be the content of the response.

    0 讨论(0)
  • 2020-12-06 18:56

    I had same issue and solved as @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;
    }
    
    0 讨论(0)
提交回复
热议问题