Почему загрузка файла POSModel не работает из папки WEB-INF?

Я использую Spring MVC для своего веб-проекта. Я поместил файлы модели в каталог WEB-INF

String taggerModelPath = "/WEB-INF/lib/en-pos-maxent.bin";
String chunkerModelPath = "/WEB-INF/lib/en-chunker.bin";

POSModel model = new POSModelLoader()
.load(new File(servletContext.getResource(taggerModelPath).toURI().getPath()));

Это работало в среде Windows. Однако, когда я развернул его на своем удаленном сервере Linux, я получил ошибку

HTTP Status 500 - Ошибка обработки запроса; Вложенное исключение - opennlp.tools.cmdline.TerminateToolException: файл модели POS Tagger не существует! Путь: /localhost/nlp/WEB-INF/lib/en-pos-maxent.bin

Каков наилучший способ доступа к файловым ресурсам? Спасибо

1 ответ

Решение

Давайте предположим, что вы используете OpenNLP 1.5.3, тогда вам следует использовать другой способ загрузки файлов ресурсов, который не использует "жестких" ссылок на пути посредством преобразования URI.

Учитывая среду, в которой в каталоге WEB-INF другой каталог resources существует, который содержит ваши файлы модели OpenNLP, ваш фрагмент кода должен быть записан следующим образом:

String taggerModelPath = "/WEB-INF/resources/en-pos-maxent.bin";
String chunkerModelPath= "/WEB-INF/resources/en-chunker.bin";

POSModel model = new POSModelLoader().load(servletContext.getResourceAsStream(taggerModelPath));

Посмотрите Javadoc для ServletContext#getResourceAsStream и этого сообщения Stackru.

Важный совет

К сожалению, есть другие проблемы с вашим кодом. Класс OpenNLP POSModelLoader только для внутреннего использования, см. официальный Javadoc для POSModelLoader:

Загружает модель POS Tagger для инструментов командной строки.

Примечание: не используйте этот класс, только для внутреннего использования!

Поэтому загрузка POSModel в веб-контексте должно быть сделано иначе: через один из доступных конструкторов этого класса. Вы можете переформулировать приведенный выше фрагмент кода следующим образом:

try {
    InputStream in = servletContext.getResourceAsStream(taggerModelPath);
    POSModel posModel;
    if(in != null) {
        posModel = new POSModel(in);

        // from here, <posModel> is initialized and you can start playing with it...
        // ...
    }
    else {
        // resource file not found - whatever you want to do in this case
    }
}
catch (IOException | InvalidFormatException ex) {
    // proper exception handling here... cause: getResourcesAsStream or OpenNLP...
} 

Таким образом, вы соответствуете API OpenNLP и в то же время делаете правильную обработку исключений. Более того, теперь вы можете использовать отладчик на случай, если что-то неясно с ссылками на пути к ресурсам файлов вашей модели.

Надеюсь, поможет.

Другие вопросы по тегам