3

我找不到将序列化 XML 的编码从默认值更改UTF-8ISO-8859-1. 我阅读了使用指南,这让我认为必须有一种方法使用XMLOutputFactorywithXmlFactory来实现这一点,但我看不到一种方法可以将这些工厂中的任何一个配置为默认使用另一种编码,只有createXMLEventWriter我可以传入的地方一种编码。

我知道如何使用ToXmlGenerator.Feature.WRITE_XML_DECLARATION. 所以我需要的是这样的声明:

<?xml version='1.0' encoding='ISO-8859-1'?>

当然,内容也应该用ISO-8859-1.

4

2 回答 2

2

源代码中,您会发现它是硬编码的:ToXmlGenerator UTF-8

if (Feature.WRITE_XML_1_1.enabledIn(_formatFeatures)) {
    _xmlWriter.writeStartDocument("UTF-8", "1.1");
} else if (Feature.WRITE_XML_DECLARATION.enabledIn(_formatFeatures)) {
    _xmlWriter.writeStartDocument("UTF-8", "1.0");
} else {
    return;
}

一旦出现ToXmlGeneratorfinal可能没有简单的方法来处理它。我已经在项目中提交了一个问题。jackson-dataformat-xml


如果您坚持使用 JAXB,则可以使用以下方法控制encoding属性的值Marshaller.JAXB_ENCODING

Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_ENCODING, "ISO-8859-1");
marshaller.marshal(foo, System.out);

看到这个答案

于 2018-10-12T12:20:27.223 回答
2

我找到的解决方案是使用带有您想要的编码的自定义 Jackson api 和 Writer 并自己打印 xml 声明。

您必须使用 Writer 包装器,因为 Jackson 使用反射(我认为它确实如此)来找出您使用的写入器类型以及它的编码是什么,并取决于它(它是否不是 UTF-8)执行字符的 XML 实体编码127. 如果您对 XML 实体编码感到满意,您可以跳过包装器。

如果你使用杰克逊的

mapper.configure(ToXmlGenerator.Feature.WRITE_XML_DECLARATION, true);

根据您的本地环境,您会面临创建无效 XML 的风险。Jackson 将始终在 xml 声明中打印 UTF-8,如果您提供具有非 utf-8 编码的流(并且某些编写器构造函数不允许您指定编码并使用平台默认值 - 这可能会在平台之间更改),您可以获得以不同于 xml 声明标题的方式编码的文档正文会让您相信。

String fileName = "/tmp/file.xml";
String encoding = "ISO-8859-1";
Writer output = new OutputStreamWriter(new FileOutputStream(fileName), encoding);

output.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\" ?>\n");
mapper.writer().writeValue(new Writer(output) {
    @Override
    public void write(char[] var1, int var2, int var3) throws IOException {
        output.write(var1, var2, var3);
    }

    @Override
    public void flush() throws IOException {
        output.flush();
    }

    @Override
    public void close() throws IOException {
        output.close();
    }

}, value);
于 2019-02-08T14:02:32.243 回答