首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JAXB2 Mtom附件被BOM打破

JAXB2 Mtom附件被BOM打破
EN

Stack Overflow用户
提问于 2011-01-13 10:28:56
回答 1查看 1.9K关注 0票数 3

我正在使用JAXB2在Spring中执行OXM。我指定的XSD需要一个大的XML文件来附加到soap消息,所以我使用MTOM来传输该文件,并在我的JAXB2Marshaller上启用了MTOM。

当JAXB2封送具有预期mime类型的文本/xml的MTOM附件时,它将该元素作为javax.xml.transform.Source对象传递。经过一些搜索之后,我能够找到如何将Source对象发送到文件中。

代码语言:javascript
复制
final Source source = request.getSource();
StreamSource streamSource = (StreamSource) source;
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
File file = new File ("/tempxmlfile.xml");
try{
    transformer.transform(streamSource, new StreamResult(file));
    LOG.info("File saved in "+file.getAbsolutePath());
    }
catch(Exception ex){
        ex.getMessage();
    }

我遇到的问题是,当我发送一个UTF-8编码文件作为附件时,我会得到以下错误:

代码语言:javascript
复制
[Fatal Error] :1:1: Content is not allowed in prolog.
ERROR:  'Content is not allowed in prolog.'

这是由文件中编码文本前面的Byte Order Mark造成的,虽然UTF-8编码文件不需要此BOM,但Unicode标准允许使用此BOM,但Java不支持UTF-8编码流中的BOM。

我可以通过发送一个没有BOM的文件来解决这个问题,但是这实际上是不可行的,因为它会在大多数Microsoft产品中引起问题,因为大多数Microsoft产品都会插入BOM。

Sun/Oracle拒绝用流解决此问题有很多解决办法,但它们都要求您能够访问流,JAXB2提供的源对象没有InputStream --它只有一个InputStream对象。我是否有办法解决这个问题,要么用一个知道如何忽略UTF-8编码中的BOM的读取器来包装source对象,要么改变JAXB2将附件读取到源中的方式,以便它可以忽略UTF-8编码中的BOM。

谢谢你,克雷格

EN

回答 1

Stack Overflow用户

发布于 2011-01-18 15:49:53

诀窍是“标记”读者。如果您的读取器不支持标记,则可以将其包装在BufferedReader中,这样可以:

  • http://download.oracle.com/javase/6/docs/api/java/io/BufferedReader.html#markSupported%28%29

选项1-检查BOM并删除它

我相信我的原始代码写错了BOM。下面的源代码更有意义:

代码语言:javascript
复制
import java.io.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    private static char[] UTF32BE = {0x00, 0x00, 0xFE, 0xFF}; 
    private static char[] UTF32LE = {0xFF, 0xFE, 0x00, 0x00};
    private static char[] UTF16BE = {0xFE, 0xFF}; 
    private static char[] UTF16LE = {0xFF, 0xFE};
    private static char[] UTF8 = {0xEF, 0xBB, 0xBF};

    public static void main(String[] args) throws Exception {
        // Create an XML document with a BOM
        FileOutputStream fos = new FileOutputStream("bom.xml");
        writeBOM(fos, UTF16LE);

        OutputStreamWriter oswUTF8 = new OutputStreamWriter(fos, "UTF-8");
        oswUTF8.write("<root/>");
        oswUTF8.close();

        // Create a Source based on a Reader to simulate source.getRequest()
        StreamSource attachment = new StreamSource(new FileReader(new File("bom.xml")));

        // Wrap reader in BufferedReader so it will support marking
        Reader reader = new BufferedReader(attachment.getReader());

        // Remove the BOM
        removeBOM(reader);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        t.transform(new StreamSource(reader), new StreamResult(System.out));
    }

    private static void writeBOM(OutputStream os, char[] bom) throws Exception {
        for(int x=0; x<bom.length; x++) {
            os.write((byte) bom[x]);
        }
    }

    private static void removeBOM(Reader reader) throws Exception {
        if(removeBOM(reader, UTF32BE)) {
            return;
        }
        if(removeBOM(reader, UTF32LE)) {
            return;
        }
        if(removeBOM(reader, UTF16BE)) {
            return;
        }
        if(removeBOM(reader, UTF16LE)) {
            return;
        }
        if(removeBOM(reader, UTF8)) {
            return;
        }
    }

    private static boolean removeBOM(Reader reader, char[] bom) throws Exception {
        int bomLength = bom.length;
        reader.mark(bomLength);
        char[] possibleBOM = new char[bomLength];
        reader.read(possibleBOM);
        for(int x=0; x<bomLength; x++) {
            if(bom[x] != possibleBOM[x]) {
                reader.reset();
                return false;
            }
        }
        return true;
    }

}

选项#2 -查找“<”并将读取器提前到那个点

阅读直到您达到“<”杠杆标记/重置:

代码语言:javascript
复制
import java.io.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

public class Demo2 {

    private static char[] UTF32BE = {0x00, 0x00, 0xFE, 0xFF}; 
    private static char[] UTF32LE = {0xFF, 0xFE, 0x00, 0x00};
    private static char[] UTF16BE = {0xFE, 0xFF}; 
    private static char[] UTF16LE = {0xFF, 0xFE};
    private static char[] UTF8 = {0xEF, 0xBB, 0xBF};

    public static void main(String[] args) throws Exception {
        // Create an XML document with a BOM
        FileOutputStream fos = new FileOutputStream("bom.xml");
        writeBOM(fos, UTF16BE);

        OutputStreamWriter oswUTF8 = new OutputStreamWriter(fos, "UTF-8");
        oswUTF8.write("<root/>");
        oswUTF8.close();

        // Create a Source based on a Reader to simulate source.getRequest()
        StreamSource attachment = new StreamSource(new FileReader(new File("bom.xml")));

        // Wrap reader in BufferedReader so it will support marking
        Reader reader = new BufferedReader(attachment.getReader());

        // Remove the BOM
        removeBOM(reader);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer t = tf.newTransformer();
        t.transform(new StreamSource(reader), new StreamResult(System.out));
    }

    private static void writeBOM(OutputStream os, char[] bom) throws Exception {
        for(int x=0; x<bom.length; x++) {
            os.write((byte) bom[x]);
        }
    }

    private static Reader removeBOM(Reader reader) throws Exception {
        reader.mark(1);
        char[] potentialStart = new char[1];
        reader.read(potentialStart);
        if('<' == potentialStart[0]) {
            reader.reset();
            return reader;
        } else {
            return removeBOM(reader);
        }
    }

}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4679028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档