web-dev-qa-db-ja.com

プロパティからint、float、boolean、stringを取得します

プロパティファイルからint、float、boolean、stringがあります。すべてがプロパティに読み込まれました。現在、特定のキーの期待値を知っているため、値を解析しています。

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

これらの定数値を設定するより良い方法は何ですか、キーのプリミティブ値のデータ型が何であるかわからない場合。

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();
    }
}

プロパティファイル。 messassge.properties

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

Constant.Java

public class Constants {
    public static String SSO_URL = null;
    public static String SSO_API_USERNAME = null;
    public static String SSO_API_PASSWORD = null;
    public static String SSO_API_SCOPE = null;
    public static boolean SSO_IS_PROXY_ENABLED = false;
    public static int SSO_MAX_RETRY_COUNT = 0;
    public static float SSO_FLOAT_VALUE = 0;
}
29

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");

コードを拡張して、より多くの型を処理できます。また、現在のように失敗する代わりに、欠落しているプロパティを無視するように変更して、フィールド宣言内の割り当てが変更されないままになるようにする、つまりデフォルトにすることができます。

29
Andreas

ダンブロスは正しいです。プロパティファイル内に保存するものはすべて文字列値です。 refのように以下のようにプロパティ値を取得した後、さまざまなプリミティブデータ型を追跡できます。 -

Javaプロパティファイル:Javaでconfig.properties値を読み取る方法

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;
    }
}

後でプリミティブに変換します- ストリングをプリミティブ型の値に変換する方法?

String型のswitchステートメントにキー値を入れてデータ型の値を追跡し、後でキー名のケースを使用して関連するデータ型の値を取得することをお勧めします。 Java 7。

5
ArifMustafa

定数のタイプがわかっている場合は、 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");

デフォルト値を使用してエラーを回避することもできます。

5
josivan

問題を正確に理解しているかどうかは完全にはわかりませんが、プロパティ値のタイプを(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
uniknow

プロパティの代わりにYAMLを使用して定数を定義し、ジャクソンを使用してクラスに逆シリアル化するdropwizard構成パターンに従います。タイプセーフ以外に、dropwizardの構成パターンは、Hibernate Validatorアノテーションが値が期待される範囲に収まることを検証できるようにすることで、さらに一歩前進します。

Dropwizardの例では...

関連するテクノロジーの詳細については...

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

Spring Bootは、 type-safe configuration プロパティに対してすぐに使用できる機能到達ソリューションを備えています。

確かに、このタスクのためだけにSpringを使用するのはやり過ぎですが、Springには多くのクールな機能があり、これは右側にあなたを引き付けることができます;)

3
Andrew Kolpakov

選択可能なクラスで構成可能なパラメーターを「静的」として定義し、静的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();
        } 
    }
}
1
Alicia