Неустрашимый XOP с 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 (данные не допускаются до пролога).

Можно ли это сделать с помощью JAXB? Создание объекта из схемы, кажется, работает нормально и создает то, что выглядит как правильный объект (он создает элемент Include). Я попытался создать AttachmentUnmarshaller вручную, но это не помогло... входящие данные все еще не распознаются как XML. Я чувствую, что упускаю фундаментальный шаг, но не могу найти хороших ссылок или примеров.

Любая помощь будет принята с благодарностью.

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. Извлеките вложения и можете набрать их на диске.
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 похоже. AttachmentUnmarshaller передается в cid и отвечает за возврат соответствующих двоичных данных. В среде JAX-WS это обрабатывается автоматически, но ничто не мешает вам делать это вручную. Вы можете найти больше информации об этом здесь: Какой самый стандартный способ Java для хранения необработанных двоичных данных вместе с 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

<foo>
    <image>
        <xop:Include xmlns:xop="http://www.w3.org/2004/08/xop/include" href="cid:http://example.org/me.jpeg"/>
    </image>
</foo>
Другие вопросы по тегам