在 Java Jersey RESTful Web 应用程序中加载属性文件,以在整个应用程序中持续存在?
Posted
技术标签:
【中文标题】在 Java Jersey RESTful Web 应用程序中加载属性文件,以在整个应用程序中持续存在?【英文标题】:Loading properties file in a Java Jersey RESTful web app, to persist throughout the app? 【发布时间】:2015-06-15 02:52:33 【问题描述】:我目前正在使用 Jersey 构建一个 RESTful API。到目前为止,一切进展顺利,但是,所有配置条目都已硬编码。(即数据库主机、数据库用户名等...)。
我希望能够设置一个存在于我的WEB-INF
文件夹中的config.properties
文件来包含所有这些配置规范。
我担心如果我以“经典”方式读取 Classpath 上的文件,我会为每个请求执行文件 I/O。我希望能够在启动时读取一次(我知道在我的web.xml
文件中涉及一个ServletListener
。
这是我下面的内容:
web.xml:
<listener>
<listener-class>com._1834Software.Config</listener-class>
</listener>
我想做这样的事情(我在 *** 上找到了 here),但我认为它不一定适用于 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);
我试着这样称呼它:
Config config = Config.getInstance(getServletContext());
String property = config.getProperty("HEROKU_DATABASE_URL");
但我收到以下错误:
Error:(32, 40) java: cannot find symbol
symbol: method getServletContext()
location: class com._1834Software.database.DatabaseHandler
这是文件(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();
【问题讨论】:
我正在使用 Intellij,但这与它有什么关系? IDE 在java: cannot find symbol
时出现编译错误。
请注意,方法 getServletContext() 没有为类 DatabaseHandler 定义,就像错误状态一样。您无法在 DatabaseHandler 中初始化配置对象,因为您无权访问 servletContext。也许向 DatabaseHandler 类添加一个新方法,该方法将 servletContext 作为参数,然后在该新方法中初始化配置。
【参考方案1】:
有很多方法可以加载属性文件。为了避免在您的项目中引入任何新的依赖项,这里有一些代码 sn-ps 可能会对您有所帮助。这只是一种方法...
定义您的属性文件。我把我的放在 src/main/resources/ 作为“config.properties”
sample.property=i am a sample property
在您的球衣配置文件中(假设您使用的是类扩展应用程序),您可以在那里加载属性文件,它只会在应用程序初始化期间加载一次,以避免您担心一遍又一遍地执行文件 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;
然后您可以像这样在端点中引用您的属性:
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");
【讨论】:
是否可以创建多个端点,如 JerseySample、JerseySample1 和 JerseySample2,并将它们添加到配置文件中,如 rootResources.add(JerseySample.class); rootResources.add(JerseySample1.class); rootResources.add(JerseySample2.class);它会起作用吗?【参考方案2】:示例:
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;
【讨论】:
以上是关于在 Java Jersey RESTful Web 应用程序中加载属性文件,以在整个应用程序中持续存在?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Security 和 Jersey Restful Web 服务进行登录身份验证
使用 Jersey 和 Spring Security 实现 RESTful Web 服务
使用 Jersey 的 RESTful Web 服务的会话管理
Java Restful框架:Jersey入门示例(官方例子)