我有一个文件,其路径类似于此/home/jwayne/test/55-0388%25car.xml
。我尝试使用JAXB将XML解组为对象,如下所示。
File file = new File("/home/jwayne/test/55-0388%25car.xml");
JAXBContext context = JAXBContext.newInstance(Rectangle.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Rectangle rectangle = (Rectangle) unmarshaller.unmarshal(file);
但是,我得到了带有堆栈跟踪的FileNotFoundException(FNFE),如下所示。
[java.io.FileNotFoundException: /home/jwayne/test/55-0388%car.xml (No such file or directory)] at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:246) at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:157) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:162) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:171) at javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:189) ...
请注意,以某种方式(如stacktrace所建议),解组器已将文件名从55-0388%25car.xml
修改为55-0388%car.xml
。
但是,逐步遍历代码,问题实际上非常严重:sun.net.www.protocol.file.Handler
具有执行以下操作的方法openConnection
。
File var4 = new File(ParseUtil.decode(var1.getPath()));
该sun.net.www.ParseUtil.decode
方法实际上可以转换文件路径。
关于如何快速解决此问题的任何想法(除了重命名文件外)? (请注意,我正在使用JDK v1.8.0_191)。
答案 0 :(得分:1)
问题的根本原因是有一个%
用于URL编码特殊字符。对于%
,它是%25
。
JAXB内部执行的操作是将%25
解码为纯%
,因此找不到该文件。
快速(又脏)的解决方案是进行一些字符串替换,例如:
String fileName = "/home/jwayne/test/55-0388%25car.xml":
fileName = fileName.replace("%25", "%2525");
File file = new File(fileName);
只要文件名中有%25
,就适用。但是我想这会发生在任何URL编码字符上。因此,如果还有其他特殊字符,则您需要为每个或某些聪明的正则表达式解决方案进行一些处理。
更新:
要解决此JAXB行为,请为其提供InputStream
而不是File
。就像这样:
FileInputStream fis = new FileInputStream(fileName);
Rectangle r2 = (Rectangle) unmarshaller.unmarshal(fis);
然后JAXB无法更改任何URI /文件名。