Unmarshalling XOP with JAXB



我有一个数据源,它已经从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。我觉得我错过了一个基本的步骤,但找不到任何好的参考或例子。

下面是一个可能有用的方法。

消息

下面是你将要处理的大致内容:

 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上键入它们。
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环境中,这是自动为您处理的,但是没有什么可以阻止您手动执行。您可以在这里找到更多相关信息:与XML一起存储原始二进制数据的最标准Java方法是什么?

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块
<foo>
    <image>
        <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http://example.org/me.jpeg"/>
    </image>
</foo>

相关内容

  • 没有找到相关文章

最新更新