使用JAXB解组XOP

时间:2014-06-25 11:24:47

标签: java xml jaxb unmarshalling xop

我有一个数据源已从base64嵌入图像数据切换到XOP图像数据。我正在使用Java / JAXB来解组数据,并且找不到任何描述它是如何完成的好资源。所有引用似乎都描述了使用SOAP消息进行此操作,这些消息似乎可以解决您的一些繁重工作。

就我而言,数据作为一个字符串有效地进入,需要将其解组为由JAXB创建的对象。由于新消息以

开头
Mime-Version: 1.0
Content-Type: multipart/related; start-info="text/xml"; type="application/xop+xml"; 
    start="<-963165769043289641.1400077877224@xxxxxyyyyyy.ca>"; 
    boundary="----=_Part_0_-338193320.1400077877317"

显然它不会将数据解组为XML,因为它看起来不像XML(在prolog之前不允许数据)。

这可以用JAXB完成吗?从模式创建对象似乎工作正常,并创建看起来像一个正确的对象(它创建一个Include元素)。我已经尝试手动创建一个AttachmentUnmarshaller但它没有帮助......传入的数据仍然没有被识别为XML。我觉得我错过了一个基本的步骤,但找不到任何好的参考或例子。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

以下是一种可能有用的方法。

消息

以下是您将要处理的内容:

 MIME-Version: 1.0
 Content-Type: Multipart/Related;boundary=MIME_boundary;
 ...
 --MIME_boundary
 Content-Type: application/xop+xml; 
 ...

 <soap:Envelope ...
  <soap:Body>...
    <foo>
      <photo xmlmime:contentType='image/png'>
        <xop:Include xmlns:xop='http://www.w3.org/2004/08/xop/include' 
           href='cid:http://example.org/me.jpeg'/></m:photo>
 ...

 --MIME_boundary
 Content-Type: image/png
 Content-Transfer-Encoding: binary
 Content-ID: <http://example.org/me.png>

 // binary octets for png

演示代码

<强>演示

以下代码假定您已处理消息以执行以下操作:

  1. 提取XML片段
  2. 提取附件,并可以在cid上键入它们。
  3. import java.io.File;
    import javax.xml.bind.*;
    
    public class Demo {
    
        private static String base64 = "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD5/ooooA//2Q==";
    
        public static void main(String[] args) throws Exception {
            // Create the JAXBContext & Unmarshaller
            JAXBContext jc = JAXBContext.newInstance(Foo.class);
            Unmarshaller unmarshaller = jc.createUnmarshaller();
    
            // Create a custom AttachementUnmarshaller.  Populate the Map
            // AttachmentUnmarshaller with the attachments keyed on the cid.
            MyAttachmentUnmarshaller attachmentUnmarshaller = new MyAttachmentUnmarshaller();
            attachmentUnmarshaller.getAttachments().put("cid:http://example.org/me.jpeg", DatatypeConverter.parseBase64Binary(base64));
    
            // Set the AttachmentUnmarshaller on the Unmarshaller
            unmarshaller.setAttachmentUnmarshaller(attachmentUnmarshaller);
    
            // Unmarshal the XML piece
            File xml = new File("src/forum24407360/input.xml");
            Foo foo = (Foo) unmarshaller.unmarshal(xml);
        }
    
    }
    

    <强> MyAttachmentUnmarshaller

    以下是AttachmentUnmarshaller的样子。在cid中传递AttachmentUnmarshaller并负责返回相应的二进制数据。在JAX-WS环境中,这将自动为您处理,但没有任何东西阻止您手动执行此操作。您可以在此处找到有关它的更多信息:What's the most standard Java way to store raw binary data along with XML?

    import java.io.*;
    import java.util.*;
    import javax.activation.*;
    import javax.xml.bind.attachment.AttachmentUnmarshaller;
    
    public class MyAttachmentUnmarshaller extends AttachmentUnmarshaller {
    
        private Map<String, byte[]> attachments = new HashMap<String, byte[]>();
    
        public Map<String, byte[]> getAttachments() {
            return attachments;
        }
    
        @Override
        public DataHandler getAttachmentAsDataHandler(String cid) {
            byte[] bytes = attachments.get(cid);
            return new DataHandler(new ByteArrayDataSource(bytes));
        }
    
        @Override
        public byte[] getAttachmentAsByteArray(String cid) {
            return attachments.get(cid);
        }
    
        @Override
        public boolean isXOPPackage() {
            return true;
        }
    
        private static class ByteArrayDataSource implements DataSource {
    
            private byte[] bytes;
    
            public ByteArrayDataSource(byte[] bytes) {
                this.bytes = bytes;
            }
    
            public String getContentType() {
                return  "application/octet-stream";
            }
    
            public InputStream getInputStream() throws IOException {
                return new ByteArrayInputStream(bytes);
            }
    
            public String getName() {
                return null;
            }
    
            public OutputStream getOutputStream() throws IOException {
                return null;
            }
    
        }
    
    }
    

    XML Piece

    <foo>
        <image>
            <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http://example.org/me.jpeg"/>
        </image>
    </foo>