我遇到了很多JAXB序列化错误,这些错误是由于代码在不同的地方创建无效的限定名造成的。我正在研究我正在使用的API和其他java XML选项,奇怪的是,实现限定名的类似乎根本不执行任何输入检查。
这确实是有问题的,因为复杂的代码会生成各种JAXB对象,直到编组时您才会发现出了严重的错误。异常堆栈通常不会告诉您哪个元素/属性是错误的,只会告诉您出了什么问题。
让这些库在一开始就让创建不可序列化内容变得更加困难,不是更有意义吗?
这是一个代码片段:为什么这样做是可行的?它不应该抛出一个IllegalArgumentException吗?在定义QName的其他API中,行为是相同的。该类的javadoc指定,如果名称空间为空,则将获得IllegalArgumentException,否则不会。
QName q = new QName("Namespace URI is supposed to be an anyURI, but clearly ISN'T",
"Local part is supposed to be an NCName, but clearly ISN'T",
"<><><><>&&& Laughably Invalid Namespace Prefix");
System.out.println(q);参考文献:Relevant javadoc for QName,spec constraints stating name is an anyURI, and localpart is an NCName。换句话说,根据规范,无论序列化如何,上面的代码都是明显无效的。
发布于 2014-04-28 22:29:47
假设在这里。
QName构造函数的主要用户很可能不是一般的Java代码本身,而是XML解析器。
XML解析是性能敏感的。如果构造函数被解析器调用,理论上解析器已经验证了语法,因此再次验证它是浪费时间。
这是95%的问题。为什么要为5%的用户付出代价。
如果需要验证QName构造函数,可以扩展QName并添加自己的代码。
例如:
public class VerifiedQName extends QName {
public VerifiedQName(String namespaceURI, String localPart) {
super(namespaceURI, localPart);
verfiyNamespaceURI(namespaceURI); // throws IllegalArgumentException
verifyLocalPart(localPart); // throws IllegalArgumentException
}
...
}至少在文档中这个类是不验证的。
发布于 2014-04-28 22:13:13
javax.xml.namespace.QName不是JAXB类,它只是JAXB利用的Java的一部分。
原因不是验证Data
String操作代价很高,您是否希望每次都检查每个String?QName要针对哪个版本的定义进行验证?在更新Java中的版本以支持它之前,您是否无法利用新的定义?QName这样的类可以容忍“无效”数据,则可以将它们用于非预期的方式。更新
你知道这些是原因吗,还是你在猜测?
纯粹是猜测,但我确实领导了JAXB的EclipseLink MOXy实现。
为什么在构造函数中检查字符串的开销会很大?
这比什么都不做要昂贵。此外,即使每个构造函数调用的成本很小,执行足够多的操作也会变得很昂贵。
值得一提的是,与规范相关的其他类型(如
和URI)都会在其构造函数中抛出无效格式的异常。
您通常不会创建大量这样的对象,因此来自异常的用户帮助超过了执行检查的成本。
还有,QNames的定义什么时候会改变?
当然,它不太可能改变。然而,目前JAXB实现通常被用来支持的不仅仅是XML。当您从另一种格式读取/写入数据时,拥有一个容错的QName实现是很方便的。
https://stackoverflow.com/questions/23342229
复制相似问题