程序中有一些情况,如下所示,我将从属性文件中获取空对象
<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.1" class="java.beans.XMLDecoder">
<object class="java.util.Map">
</object>
</java>
在下面的代码中读取空对象
public Object translateObj(
String data,
PropertyDefinition propDef) {
try {
XMLDecoder decoder =
new XMLDecoder(new BufferedInputStream(new ByteArrayInputStream(data.getBytes("UTF-8"))));
Object object = decoder.readObject();
decoder.close();
return object;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("XmlNativeTranslator.translateFromStorage: " +
" Unable to UTF-8 encode inputData " + data.toString());
} catch (ArrayIndexOutOfBoundsException e) {
StringBuffer s = new StringBuffer();
s.append("Failed to translate property definition key [");
s.append(propDef.getKey());
s.append("] XML contents [");
s.append(data.toString());
s.append("]");
throw new RuntimeException(s.toString(), e);
}
}
在尝试读取上面的代码中的行解码器中的空对象时,readObject()我遇到以下错误
java.lang.RuntimeException:XmlNativeTranslator.translateFromStorage: 无法转换属性定义键[FORMS_KEY] XML 内容[]造成原因: java.lang.ArrayIndexOutOfBoundsException:0
需要一种解决这种情况的方法
答案 0 :(得分:0)
java.util.Map
是一个接口,您永远不要以序列化的形式遇到它,因为不可能有接口的直接实例。
例如,空地图的有效表达式为
<object class="java.util.HashMap"/>
或
<object class="java.util.Collections" method="emptyMap"/>
或
<object class="java.util.Properties"/>
XMLDecoder
具有在特殊情况下继续进行操作的可疑功能,这会导致ArrayIndexOutOfBoundsException
作为后续错误。
您可以强制其引发实际异常:
XMLDecoder dec = new XMLDecoder(new InputSource(new StringReader(data)));
dec.setExceptionListener(ex -> {
throw ex instanceof RuntimeException? (RuntimeException)ex:
new RuntimeException("Failed to translate property definition key"+
" ["+propDef.getKey()+"] XML contents ["+data+"]", ex);
});
Object object = dec.readObject();
return object;
请注意,使用StringReader
不会处理任何编码错误。我还删除了close()
步骤,因为StringReader
没有附加资源,在特殊情况下,当我们使用try-with-resource时,XMLDecoder.close()
会导致更多后续错误。
此处手动使用StringBuffer
不能比字符串串联更好。在Java 5之前,编译器将生成几乎相同的代码,因为Java 5使用StringBuilder
生成了相似的代码,效率更高,更不用说Java 9和更高版本了。
在示例输入中运行此代码会产生
Exception in thread "main" java.lang.RuntimeException: Failed to translate property definition key [] XML contents [<?xml version="1.0" encoding="UTF-8"?>
<java version="1.4.1" class="java.beans.XMLDecoder">
<object class="java.util.Map">
</object>
</java>]
at ListFiltersToGetMatchingRecords.lambda$main$0(ListFiltersToGetMatchingRecords.java:35)
at com.sun.beans.decoder.DocumentHandler.handleException(DocumentHandler.java:359)
at com.sun.beans.decoder.NewElementHandler.getValueObject(NewElementHandler.java:126)
at com.sun.beans.decoder.ElementHandler.endElement(ElementHandler.java:169)
at com.sun.beans.decoder.DocumentHandler.endElement(DocumentHandler.java:318)
… shortened …
at com.sun.beans.decoder.DocumentHandler.parse(DocumentHandler.java:372)
at java.beans.XMLDecoder$1.run(XMLDecoder.java:201)
at java.beans.XMLDecoder$1.run(XMLDecoder.java:199)
at java.security.AccessController.doPrivileged(Native Method)
at java.beans.XMLDecoder.parsingComplete(XMLDecoder.java:199)
at java.beans.XMLDecoder.readObject(XMLDecoder.java:250)
at ListFiltersToGetMatchingRecords.main(ListFiltersToGetMatchingRecords.java:38)
Caused by: java.lang.InstantiationException: java.util.Map
at java.lang.Class.newInstance(Class.java:427)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
… shortened …
at java.beans.Statement.invoke(Statement.java:182)
at java.beans.Expression.getValue(Expression.java:155)
at com.sun.beans.decoder.ObjectElementHandler.getValueObject(ObjectElementHandler.java:166)
at com.sun.beans.decoder.NewElementHandler.getValueObject(NewElementHandler.java:123)
... 24 more
Caused by: java.lang.NoSuchMethodException: java.util.Map.<init>()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 42 more