【问题标题】:Why does the loading of a POSModel file not work from inside the WEB-INF folder?为什么不能从 WEB-INF 文件夹中加载 POSModel 文件?
【发布时间】:2015-08-21 19:54:58
【问题描述】:

我正在为我的 Web 项目使用 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 状态 500 - 请求处理失败;嵌套异常是 opennlp.tools.cmdline.TerminateToolException:POS Tagger 模型文件不存在!路径:/localhost/nlp/WEB-INF/lib/en-pos-maxent.bin

访问文件资源的最佳方式是什么?谢谢

【问题讨论】:

  • 该文件是否存在于您的远程 Linux 服务器上?
  • 是的,它在 WEB-INF/lib 文件夹中。

标签: java tomcat servlets opennlp resource-loading


【解决方案1】:

假设您使用的是 OpenNLP 1.5.3,那么您应该使用另一种加载资源文件的方式,即不通过 URI 转换使用“硬”路径引用。

假设在WEB-INF 目录中存在另一个包含您的OpenNLP 模型文件的目录resources 的环境,您的代码片段应编写如下:

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 和此 StackOverflow post

重要提示

很遗憾,您的代码还存在其他问题。 OpenNLP 类POSModelLoader 仅供内部 使用,请参阅POSModelLoader 的官方Javadoc:

为命令行工具加载一个词性标注模型。

注意:不要使用这个类,仅供内部使用!

因此,在 Web 上下文中加载 POSModel 应该以不同的方式完成:通过可用的 constructors of that class 之一。您可以像这样重新编写上面的代码片段:

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

这样,您既符合 OpenNLP API 的要求,同时也可以进行适当的异常处理。此外,您现在可以使用调试器,以防模型文件的资源路径引用仍不清楚。

希望对你有帮助。

【讨论】:

  • 谢谢我的朋友!看来我的应用程序每次查询时都会加载 opennlp 模型。我应该使用单例模式吗?
  • 您可以在当前类的构造函数中调用上述代码,并在需要时将 posmodel 作为字段引用。因此,它应该只加载一次。其他想法通常需要详细了解应用程序架构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-11
  • 2014-12-07
相关资源
最近更新 更多