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

时间:2012-06-03 20:55:21

标签: java jsf

这是我项目的Maven结构

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

common-module公开Version课程。 Web应用程序和批处理模块都使用此类。

Version类有一个名为get的唯一静态方法。它返回项目的全局版本。

全局版本存储在属性文件中。从批处理模块(独立的Java应用程序)调用get时,属性文件已成功加载。

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

FacesContext.getCurrentInstance().getExternalContext()

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

Thread.currentThread().getClassLoader()

我永远找不到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();
    }
}

Version.java

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

        // Read InputStream and return version string ...
    }
}

2 个答案:

答案 0 :(得分:11)

我不确定Maven如何构建WAR以及您的属性文件实际所在的位置,但我至少可以告诉ExternalContext#getResourceAsStream()Thread#getContextClassLoader()和{{ 1}}所有工作都不同。

  1. <强>的ExternalContext#的getResourceAsStream()
    Class#getClassLoader()扫描web内容文件夹中的webapp资源(WAR ExternalContext#getResourceAsStream()/WEB-INF文件夹所在的位置)和/META-INF文件夹中部署的/META-INF/resources文件夹/WEB-INF/lib 1)}的webapp。提供的路径始终相对于那些根文件夹,应以/开头。

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

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

    InputStream input = VersionBean.class
        .getResourceAsStream("version.properties");
    

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

    InputStream input = VersionBean.class
        .getResourceAsStream("/com/example/other/version.properties");
    

答案 1 :(得分:0)

我会将属性文件的加载委托给类Version的同一个类加载器:在方法get中,使用Version.class.getResourceAsStream("yourFile.properties");

这应该适用于可以加载Version类的任何地方,因此它也可以在webapp中工作(当然,如果 common-module 中的属性文件实际上是 IS > jar文件:)。

然后你的VersionBean可能是一个应用程序范围的bean,只是在初始化应用程序时加载了属性,如下所示:

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

请注意,如果您在2.0之前使用JSF版本,则必须在faces-config.xml中配置托管bean,而不是使用注释@ManagedBean@ApplicationScoped。< / p>