2

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

任何帮助将不胜感激。

4

1 回答 1

2

以下是一种可能会有所帮助的方法。

信息

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

 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);
    }

}

我的附件解组器

下面是AttachmentUnmarshaller外观。anAttachmentUnmarshaller在cid中传入,负责返回对应的二进制数据。在 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>
于 2014-06-25T19:32:09.450 回答