在 Java Jersey RESTful Web 应用程序中加载属性文件,以在整个应用程序中持续存在?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29543597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 15:28:08  来源:igfitidea点击:

Loading properties file in a Java Jersey RESTful web app, to persist throughout the app?

javaxmljerseyconfigproperties-file

提问by carbon_ghost

I'm currently building a RESTful API using Jersey. So far, all has been going well, however, all of the configuration entries have been hard coded in. (i.e. Database Host, Database Username, etc...).

我目前正在使用 Jersey 构建一个 RESTful API。到目前为止,一切都进行得很顺利,但是,所有的配置条目都已被硬编码。(即数据库主机数据库用户名等...)。

I'd like to be able to setup a config.propertiesfile that exists in my WEB-INFfolder to contain all of these configuration specs.

我希望能够设置一个config.properties存在于我的WEB-INF文件夹中的文件来包含所有这些配置规范。

I'm concerned that if I do it the "classic" way of reading the file on the Classpath, I'm performing file I/O for every request. I want to be able to read once on startup (which I know involves a ServletListenerin my web.xmlfile.

我担心如果我以“经典”的方式读取类路径上的文件,我会为每个请求执行文件 I/O。我希望能够在启动时读取一次(我知道这涉及ServletListener我的web.xml文件中的 a 。

Here's what I have below:

这是我在下面的内容:

web.xml:

网页.xml:

<listener>
    <listener-class>com._1834Software.Config</listener-class>
</listener>

I'd like to do something like this (which I found hereon StackOverflow) but I don't think it works necessarily with Jersey:

我想做这样的事情(我在 StackOverflow 上找到),但我认为它不一定适用于 Jersey:

Config.java

配置文件

public class Config implements ServletContextListener {
    private static final String ATTRIBUTE_NAME = "config";
    private Properties config = new Properties();

    @Override
    public void contextInitialized(ServletContextEvent event) {
        try {

            config.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties"));

        } catch (IOException err) {
            err.printStackTrace();
        }

        event.getServletContext().setAttribute(ATTRIBUTE_NAME, this);

    }

    @Override
    public void contextDestroyed(ServletContextEvent event) { /**/ }

    public static Config getInstance(ServletContext context) {
        return (Config) context.getAttribute(ATTRIBUTE_NAME);
    }

    public String getProperty(String key) {
        return config.getProperty(key);
    }

}

I try to call it like such:

我试着这样称呼它:

Config config = Config.getInstance(getServletContext());
String property = config.getProperty("HEROKU_DATABASE_URL");

But I get the following error:

但我收到以下错误:

Error:(32, 40) java: cannot find symbol
symbol:   method getServletContext()
location: class com._1834Software.database.DatabaseHandler

And here is the file (DatabaseHandler.javawhere I'm trying to call it):

这是文件(DatabaseHandler.java我试图调用它的地方):

public class DatabaseHandler {
    public Connection connection = null;

    Config config = Config.getInstance(getServletContext());
    String property = config.getProperty("somekey");


    /* Database Parameters */
    private String DRIVER = "org.postgresql.Driver";
    private String host = "XXXXX";
    private String userName = "XXXXX";
    private String password = "XXXXX";

    public void connect() throws SQLException {
        try {

            Class.forName(DRIVER);

        } catch (ClassNotFoundException err) {

            err.printStackTrace();   

        }

        try {

            connection = DriverManager.getConnection(host, userName, password);

        } catch (SQLException err) {
            err.printStackTrace();
        }
    }

    public void disconnect() throws SQLException { connection.close(); }
}

回答by David Fleeman

There are many ways to load properties files. To avoid introducing any new dependencies on your project, here are some code snippets that may help you. This is just one approach...

加载属性文件的方法有很多种。为了避免在您的项目中引入任何新的依赖项,这里有一些可能对您有所帮助的代码片段。这只是一种方法......

  1. Define your properties file. I put mine in src/main/resources/ as "config.properties"

    sample.property=i am a sample property
    
  2. In your jersey config file (assuming you are using class extending Application), you can load the properties file there and it will only be loaded once during the application initialization to avoid your concern of doing the File I/O over and over:

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashSet;
    import java.util.Properties;
    import java.util.Set;
    
    import javax.ws.rs.ApplicationPath;
    import javax.ws.rs.core.Application;
    
    @ApplicationPath("sample")
    public class JerseyConfig extends Application {
    
    public static final String PROPERTIES_FILE = "config.properties";
    public static Properties properties = new Properties();
    
    private Properties readProperties() {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
        if (inputStream != null) {
            try {
                properties.load(inputStream);
            } catch (IOException e) {
                // TODO Add your custom fail-over code here
                e.printStackTrace();
            }
        }
        return properties;
    }
    
    @Override
    public Set<Class<?>> getClasses() {     
        // Read the properties file
        readProperties();
    
        // Set up your Jersey resources
        Set<Class<?>> rootResources = new HashSet<Class<?>>();
        rootResources.add(JerseySample.class);
        return rootResources;
    }
    
    }
    
  3. Then you can reference your properties in your endpoints like this:

    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    
    @Path("/")
    public class JerseySample {
    
        @GET
        @Path("hello")
        @Produces(MediaType.TEXT_PLAIN)
        public String get() {
            return "Property value is: " + JerseyConfig.properties.getProperty("sample.property");
        }
    
    }
    
  1. 定义您的属性文件。我把我的放在 src/main/resources/ 作为“config.properties”

    sample.property=i am a sample property
    
  2. 在您的 jersey 配置文件中(假设您正在使用类扩展应用程序),您可以在那里加载属性文件,并且它只会在应用程序初始化期间加载一次,以避免您担心一遍又一遍地执行文件 I/O:

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.HashSet;
    import java.util.Properties;
    import java.util.Set;
    
    import javax.ws.rs.ApplicationPath;
    import javax.ws.rs.core.Application;
    
    @ApplicationPath("sample")
    public class JerseyConfig extends Application {
    
    public static final String PROPERTIES_FILE = "config.properties";
    public static Properties properties = new Properties();
    
    private Properties readProperties() {
        InputStream inputStream = getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
        if (inputStream != null) {
            try {
                properties.load(inputStream);
            } catch (IOException e) {
                // TODO Add your custom fail-over code here
                e.printStackTrace();
            }
        }
        return properties;
    }
    
    @Override
    public Set<Class<?>> getClasses() {     
        // Read the properties file
        readProperties();
    
        // Set up your Jersey resources
        Set<Class<?>> rootResources = new HashSet<Class<?>>();
        rootResources.add(JerseySample.class);
        return rootResources;
    }
    
    }
    
  3. 然后,您可以在端点中引用您的属性,如下所示:

    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import javax.ws.rs.Produces;
    import javax.ws.rs.core.MediaType;
    
    @Path("/")
    public class JerseySample {
    
        @GET
        @Path("hello")
        @Produces(MediaType.TEXT_PLAIN)
        public String get() {
            return "Property value is: " + JerseyConfig.properties.getProperty("sample.property");
        }
    
    }
    

回答by H?i Nguy?n Hoàng

example:

例子:

private static String token;
static {
    token = getProperties().getProperty("token");
}

public static Properties getProperties() {
    Properties _properties = new Properties();

    try (InputStream inputStream = new FileInputStream("src/main/resources/app.properties")) {
        _properties.load(inputStream);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return _properties;
}