从Properties中获取int,float,boolean和string

时间:2016-04-19 16:09:09

标签: java constants properties-file

我有属性文件中的int,float,boolean和string。所有东西都加载了属性。目前,我正在解析值,因为我知道特定键的预期值。

# set up the output data.frame
Output2 <- data.frame(do.call(rbind, intermediate))
names(Output2) <- c("ColB", "Output")

# here is the core, which does the element matching
foundMatch <- apply(Output2, 1, function(x) {
    tokens <- strsplit(x, " ", fixed = TRUE)
    all(tokens[[2]] %in% tokens[[1]])
})
# filter out the ones with the match
Output2 <- Output2[foundMatch, ]

Output2
##             ColB Output
## 1  A B C D X Y Z    A B
## 2  C D M N F K L    A B
## 3  S H A F R M T    A B
## 10 A B C D X Y Z    E F
## 14 C D M N F K L    G H
## 20 C D M N F K L      M
## 21 S H A F R M T      M

设置这些常量值的更好方法是,如果我不知道键的原始值数据类型是什么。

Boolean.parseBoolean("false");
Integer.parseInt("3")

属性文件。 messassge.properties

public class Messages {

    Properties appProperties = null;
    FileInputStream file = null;

    public void initialization() throws Exception {

        appProperties = new Properties();
        try {

            loadPropertiesFile();

        } catch (Exception e) {
            throw new Exception(e.getMessage(), e);
        }
    }

    public void loadPropertiesFile() throws IOException {

        String path = "./cfg/message.properties";
        file = new FileInputStream(path);
        appProperties.load(file);
        file.close();
    }
}

Constant.java

SSO_URL = https://example.com/connect/token
SSO_API_USERNAME = test
SSO_API_PASSWORD = Uo88YmMpKUp
SSO_API_SCOPE = intraday_api
SSO_IS_PROXY_ENABLED = false
SSO_MAX_RETRY_COUNT = 3
SSO_FLOAT_VALUE = 3.0

8 个答案:

答案 0 :(得分:27)

如果你有一类配置值,比如你的Constants类,并且你想从配置(属性)文件加载所有值,你可以创建一个小帮助类并使用反射:

public class ConfigLoader {
    public static void load(Class<?> configClass, String file) {
        try {
            Properties props = new Properties();
            try (FileInputStream propStream = new FileInputStream(file)) {
                props.load(propStream);
            }
            for (Field field : configClass.getDeclaredFields())
                if (Modifier.isStatic(field.getModifiers()))
                    field.set(null, getValue(props, field.getName(), field.getType()));
        } catch (Exception e) {
            throw new RuntimeException("Error loading configuration: " + e, e);
        }
    }
    private static Object getValue(Properties props, String name, Class<?> type) {
        String value = props.getProperty(name);
        if (value == null)
            throw new IllegalArgumentException("Missing configuration value: " + name);
        if (type == String.class)
            return value;
        if (type == boolean.class)
            return Boolean.parseBoolean(value);
        if (type == int.class)
            return Integer.parseInt(value);
        if (type == float.class)
            return Float.parseFloat(value);
        throw new IllegalArgumentException("Unknown configuration value type: " + type.getName());
    }
}

然后你这样称呼它:

ConfigLoader.load(Constants.class, "/path/to/constants.properties");

您可以扩展代码以处理更多类型。您也可以将其更改为忽略缺失的属性,而不是像现在那样失败,这样字段声明中的赋值将保持不变,即默认值。

答案 1 :(得分:5)

如果您知道常量的类型,则可以使用Apache Commons Collections

例如,您可以根据常量的类型使用一些实用程序方法。

booelan SSO_IS_PROXY_ENABLED = MapUtils.getBooleanValue(appProperties, "SSO_IS_PROXY_ENABLED", false);
String SSO_URL = MapUtils.getString(appProperties, "SSO_URL", "https://example.com/connect/token");

您甚至可以使用默认值来避免错误。

答案 2 :(得分:5)

Dambros是对的,您在Properties文件中存储的所有内容都是String值。 您可以在检索属性值后跟踪不同的原始数据类型,如下所示。 -

Java Properties File: How to Read config.properties Values in Java?

package crunchify.com.tutorial;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;

/**
 * @author Crunchify.com
 * 
 */

public class CrunchifyGetPropertyValues {
    String result = "";
    InputStream inputStream;

    public String getPropValues() throws IOException {

        try {
            Properties prop = new Properties();
            String propFileName = "config.properties";

            inputStream = getClass().getClassLoader().getResourceAsStream(propFileName);

            if (inputStream != null) {
                prop.load(inputStream);
            } else {
                throw new FileNotFoundException("property file '" + propFileName + "' not found in the classpath");
            }

            Date time = new Date(System.currentTimeMillis());

            // get the property value and print it out
            String user = prop.getProperty("user");
            String company1 = prop.getProperty("company1");
            String company2 = prop.getProperty("company2");
            String company3 = prop.getProperty("company3");

            result = "Company List = " + company1 + ", " + company2 + ", " + company3;
            System.out.println(result + "\nProgram Ran on " + time + " by user=" + user);
        } catch (Exception e) {
            System.out.println("Exception: " + e);
        } finally {
            inputStream.close();
        }
        return result;
    }
}

然后转换为原始 - How to convert String to primitive type value?

我建议您通过将键值放在String类型的switch语句中来跟踪数据类型值,然后使用键名称case检索相关的数据类型值。 在Java 7之后可以使用字符串类型切换案例。

答案 3 :(得分:4)

不完全确定我是否完全理解该问题,但可能是在(String)值中包含属性值的类型。例如,您展示的属性将变为:

SSO_URL = URL:https://example.com/connect/token
SSO_API_USERNAME = STRING:test
SSO_API_PASSWORD = STRING:Uo88YmMpKUp
SSO_API_SCOPE = STRING:intraday_api
SSO_IS_PROXY_ENABLED = BOOLEAN:false
SSO_MAX_RETRY_COUNT = INTEGER:3
SSO_FLOAT_VALUE = FLOAT:3.0

在解析属性值期间,首先通过查看:之前的部分来确定属性的类型,然后使用后面的部分进行实际解析。

private static Object getValue(Properties props, String name) {
    String propertyValue = props.getProperty(name);
    if (propertyValue == null) {
        throw new IllegalArgumentException("Missing configuration value: " + name); 
    } else {
        String[] parts = string.split(":");
        switch(parts[0]) {
            case "STRING":
                return parts[1];
            case "BOOLEAN":
                return Boolean.parseBoolean(parts[1]);
            ....
            default:
                throw new IllegalArgumentException("Unknown configuration value type: " + parts[0]);
        }
    }
 }

答案 4 :(得分:4)

按照dropwizard配置模式,使用YAML而不是Properties定义常量,并使用Jackson将其反序列化为类。除了类型安全之外,dropwizard的配置模式更进一步,允许Hibernate Validator注释验证值是否属于您的预期范围。

对于dropwizard的例子......

有关所涉及技术的更多信息......

  • github.com/FasterXML/jackson-dataformat-yaml
  • hibernate.org/validator /

答案 5 :(得分:3)

Spring Boot已准备就绪,可用于type-safe configuration属性的功能扩展解决方案。

当然,使用Spring只是为了完成这项任务有点过分,但Spring有很多很酷的功能,这个功能可以吸引你到右边;)

答案 6 :(得分:0)

您可以在选择的类中将可配置参数定义为“静态”,然后从静态init调用一种从属性文件中加载参数值的方法。

例如:

public class MyAppConfig {

    final static String propertiesPath="/home/workspace/MyApp/src/config.properties";
    static String strParam;
    static boolean boolParam;
    static int intParam;
    static double dblParam;

    static {

       // Other static initialization tasks...
       loadParams();
    }

    private static void loadParams(){

        Properties prop = new Properties();

        try (InputStream propStream=new FileInputStream(propertiesPath)){           
            // Load parameters from config file
            prop.load(propStream);
            // Second param is default value in case key-pair is missing
            strParam=prop.getProperty("StrParam", "foo");
            boolParam=Boolean.parseBoolean(prop.getProperty("boolParam", "false")); 
            intParam= Integer.parseInt(prop.getProperty("intParam", "1")); 
            dblParam=Double.parseDouble(prop.getProperty("dblParam", "0.05")); 

        } catch (IOException e) {
            logger.severe(e.getMessage());
            e.printStackTrace();
        } 
    }
}

答案 7 :(得分:-1)

这可能会有所帮助:

props.getProperty("name", Integer.class);