JAXB не может загрузить файл с именем, содержащим символы в кодировке URL - PullRequest
0 голосов
/ 11 января 2019

У меня есть файл, путь которого выглядит так /home/jwayne/test/55-0388%25car.xml. Я пытаюсь демонтировать XML обратно в объект, используя JAXB, следующим образом.

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)
...

Обратите внимание, что каким-то образом (как предполагает трассировка стека) демонмаршаллер изменил имя файла с 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 голосов
/ 11 января 2019

Основной причиной вашей проблемы является то, что % используется для 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 / имени файла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...