JAXB无法加载名称包含URL编码字符的文件

时间:2019-01-11 01:22:53

标签: java jaxb

我有一个文件,其路径类似于此/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)。

1 个答案:

答案 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 /文件名。