Неустрашимый 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
Демонстрационный код
демонстрация
Код ниже предполагает, что вы обработали сообщение, чтобы сделать следующее:
- Извлечь фрагмент XML
- Извлеките вложения и можете набрать их на диске.
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>