使用JSF从JAR文件中加载属性文件

Ste*_*han 2 java jsf

这是我项目的Maven结构

app
  > common-module
  > webapp-module
  > batch-module
 pom.xml

common-module公开一个Version类.webapp和批处理模块都使用此类.

Version班有一个所谓的独特的静态方法get.它返回项目的全局版本.

全局版本存储在属性文件中.当get从批料模块(一个独立的Java应用程序)调用,属性文件成功加载.

在webapp中,情况有所不同.我创建了一个托管bean VersionBean,允许任何JSF页面调用该get方法.每当我使用以下之一时

FacesContext.getCurrentInstance().getExternalContext()

FacesContext.getCurrentInstance().getExternalContext().getContext()

Thread.currentThread().getClassLoader()
Run Code Online (Sandbox Code Playgroud)

我永远找不到properties.file.

如何从托管bean加载位于jar文件中的属性文件(getResourceAsStream)?

编辑
这是我根据@BalusC和@eljunior的建议提出的解决方案

VersionBean.java

@ManagedBean(eager=true)
@ApplicationScoped
public class VersionBean {
    private String version;
    @PostConstruct
    public void init(){
        version = Version.get();
    }
}
Run Code Online (Sandbox Code Playgroud)

Version.java

public class Version {
    public static String get() {
        InputStream is = Version.class.getResourceAsStream("/version.properties");

        // Read InputStream and return version string ...
    }
}
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 11

我不确定Maven如何构建WAR以及你的属性文件实际位于何处,但我至少可以告诉你如何ExternalContext#getResourceAsStream(), Thread#getContextClassLoader()并且Class#getClassLoader()所有工作方式都不同.

  1. 的ExternalContext#的getResourceAsStream()
    ExternalContext#getResourceAsStream()网页内容的文件夹中的web应用资源扫描(那里的WAR的/WEB-INF/META-INF文件夹也驻留)和/META-INF/resources部署在任何JAR文件的文件夹/WEB-INF/lib的web应用.提供的路径始终相对于那些根文件夹,应以a开头/.

    InputStream input = externalContext
        .getResourceAsStream("/WEB-INF/version.properties");
    
    Run Code Online (Sandbox Code Playgroud)
  2. 线程#getContextClassLoader()
    Thread#getContextClassLoader()在类路径的"根"的动作.这涵盖了webapp的类路径,appserver和JVM所涵盖的所有文件夹.提供的路径始终相对于类路径根,并且不能/.请注意,当属性文件包含在包中时,您应该将包结构视为具有/分隔符的文件系统路径.以下示例假定它在包中com.example.version.

    InputStream input = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream("com/example/version/version.properties");
    
    Run Code Online (Sandbox Code Playgroud)
  3. 类#getClassLoader()
    Class#getClassLoader()操作相对于所述类本身的位置.提供的路径可以是相对路径或绝对路径.如果是相对的,则它相对于类本身的位置.如果是绝对的,那么它对类路径根是绝对的.请注意,这不一定可以访问类路径所涵盖的所有其他文件夹.以下示例假定属性文件与VersionBean类位于同一个包中:

    InputStream input = VersionBean.class
        .getResourceAsStream("version.properties");
    
    Run Code Online (Sandbox Code Playgroud)

    或者当它在另一个包中时,例如com.example.other(注意领先/):

    InputStream input = VersionBean.class
        .getResourceAsStream("/com/example/other/version.properties");
    
    Run Code Online (Sandbox Code Playgroud)