Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 成功编组后无法\u0000解组_Java_Xml_Unicode_Jaxb - Fatal编程技术网

Java 成功编组后无法\u0000解组

Java 成功编组后无法\u0000解组,java,xml,unicode,jaxb,Java,Xml,Unicode,Jaxb,我在UTF-8中有一个包含二进制0的字符串(“a\u0000B”)。JAXB愉快地封送包含此类字符的XML文档,但随后无法将其解组: final JAXBContext jaxbContext = JAXBContext.newInstance(Root.class); final Marshaller marshaller = jaxbContext.createMarshaller(); final Unmarshaller unmarshaller = jaxbContext.create

我在UTF-8中有一个包含二进制
0
字符串(
“a\u0000B”
)。JAXB愉快地封送包含此类字符的XML文档,但随后无法将其解组:

final JAXBContext jaxbContext = JAXBContext.newInstance(Root.class);
final Marshaller marshaller = jaxbContext.createMarshaller();
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

Root root = new Root();
root.value = "A\u0000B";

final ByteArrayOutputStream os = new ByteArrayOutputStream();
marshaller.marshal(root, os);

unmarshaller.unmarshal(new ByteArrayInputStream(os.toByteArray()));
根类很简单:

@XmlRootElement
class Root { @XmlValue String value; }
输出XML包含二进制
0
,以及
A
B
(十六进制:
41 00 42
)之间的XML,在解组过程中会导致以下错误:

org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 63; 
An invalid XML character (Unicode: 0x0) was found in the element content of the document.
有趣的是,使用原始domapi()生成转义的
0
A�;B
但试图读回它会产生类似的错误。另外,任何XML解析器或
xmllint
都不允许使用
0
(既不是二进制的也不是转义的)

我的问题是:
  • 为什么JAXB/DOM API允许创建它无法读回的无效XML文档?它在编组时不应该快速失效吗

  • 是否有一些优雅的全球解决方案?我看到人们通过以下方式解决这个问题:

    • 甚至

但是,Java中成熟的XML堆栈(我使用的是1.7.0_05)不应该默认或通过一些简单的设置来处理这个问题吗?我正在寻找转义、忽略或快速失败——但是生成无效XML的默认行为是不可接受的。我相信这样的基本功能不需要在客户端进行任何额外的编码

为什么JAXB/DOM API允许创建它无法读回的无效XML文档?它在编组时不应该快速失效吗

  • 您需要询问实施者

  • 可能他们认为检查每个序列化的数据字符的费用是不合理的。。。特别是当解析器再次检查它们时

  • 在决定以这种方式实现序列化程序(或者只是错误地实现了序列化程序)之后,如果他们在默认情况下将行为更改为执行严格检查,那么他们将破坏依赖于能够序列化非法XML的现有代码

  • 但是,Java中成熟的XML堆栈(我使用的是1.7.0_05)不应该默认或通过一些简单的设置来处理这个问题吗

    不一定。。。如果你接受上面第2条的理由。即使是简单的设置也会对性能产生可测量的影响


    此外,任何XML解析器或xmllint都不允许0(既不是二进制的,也不是转义的)

    完全正确!XML规范禁止这样做

    然而,一个更有趣的测试是,当您试图使用其他XML堆栈生成包含非法字符的XML时,会发生什么情况


    是否有一些优雅的全球解决方案

    如果您试图解决的问题是如何发送
    \u0000
    \u000B
    ,则需要在将字符串插入DOM之前对其应用特定于应用程序的编码。另一端需要部署等效的解码


    如果您试图解决的问题是如何在太晚之前检测坏数据,那么您可以在序列化程序和最终输出流之间使用输出流过滤器来实现这一点。但是,如果检测到不好的地方,就没有好的(即对XML使用者透明的)方法来修复它

    我最近编写了一些测试用例来测试我是否处理了“一个无效的XML字符(Unicode:0x0)”场景,如果我知道我可以实际使用封送处理程序添加注入空值(而不是直接编辑字符串),我的生活会更轻松但我怀疑这是原因。请看,如果必须转义,序列化程序必须检查每个字符(例如,“阅读我的1.答案。询问实施者!谢谢你的全面回答。我不相信绩效是一个问题,但这很难回答,同意。但是我不同意以没有建设性的方式结束问题。我不仅仅是问为什么?(我认为这有一些文件证明的原因-在哪里,答案可能非常有建设性)但也有如何解决这种行为或解决问题。无论如何,谢谢。我投票结束的原因是这样的问题:“为什么JAXB/DOM API允许创建无法读回的无效XML文档?它是否应该在编组过程中快速失败?”和“但Java中成熟的XML堆栈(我使用的是1.7.0_05)不应该默认或通过一些简单的设置来处理此问题?”这些显然是不客观的……和(IMO)邀请进行非建设性辩论。