web-dev-qa-db-fra.com

Récupère int, float, boolean et string à partir de Properties

J'ai int, float, boolean et string à partir du fichier de propriétés. Tout a été chargé dans Propriétés. Actuellement, j'analyse les valeurs car je connais la valeur attendue pour une clé particulière.

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

Quel est le meilleur moyen de définir ces valeurs constantes, Si je ne sais pas ce que pourrait être le type de données valeur primitive pour une clé.

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

Fichier de propriétés . 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;
}
26

Si vous avez une classe de valeurs de configuration, telle que votre classe Constants, et que vous souhaitez charger toutes les valeurs à partir d'un fichier de configuration (propriétés), vous pouvez créer une petite classe d'assistance et utiliser la réflexion:

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

Ensuite, vous l'appelez comme ceci:

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

Vous pouvez étendre le code pour gérer plus de types. Vous pouvez également le changer pour ignorer les propriétés manquantes, au lieu d’échouer de la même manière que maintenant, de sorte que les affectations dans la déclaration de champ restent inchangées, c’est-à-dire par défaut.

25
Andreas

Dambros a raison, tout ce que vous stockez dans un fichier de propriétés a la forme d'une chaîne . Vous pouvez suivre vos différents types de données primitives après avoir récupéré la valeur de la propriété, comme ci-dessous, comme le ref. -

Fichier de propriétés Java: Comment lire les valeurs de config.properties en 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;
    }
}

et plus tard, convertir en primitive - Comment convertir une chaîne en valeur de type primitif?

Je vous suggère de suivre votre valeur de type de données en plaçant les valeurs de clé dans une instruction switch de type String, puis de récupérer la valeur de type de données associée à l'aide de cas de noms de clé . Le cas de changement de type de chaîne est possible après Java 7.

5
ArifMustafa

Si vous connaissez le type de constante, vous pouvez utiliser Apache Commons Collections .

Par exemple, vous pouvez utiliser une méthode d’utilité en fonction du type de votre constante.

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

Vous pouvez même utiliser des valeurs par défaut pour éviter les erreurs.

5
josivan

Pas tout à fait sûr de bien comprendre le problème, mais une possibilité pourrait être d’inclure le type de la valeur de la propriété dans la valeur (String). Ainsi, par exemple, les propriétés que vous avez montrées deviendraient quelque chose comme:

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

Lors de l'analyse des valeurs de propriété, vous déterminez d'abord le type de la propriété en consultant la partie précédant : et en utilisant la partie suivante pour l'analyse en cours. 

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

Suivez le modèle de configuration de dropwizard dans lequel vous définissez vos constantes en utilisant YAML au lieu de Propriétés et utilisez Jackson pour le désérialiser dans votre classe. Outre le type de sécurité, le modèle de configuration de dropwizard va encore plus loin en permettant aux annotations d'Hibernate Validator de valider que les valeurs se situent dans les plages prévues.

Pour l'exemple de dropwizard ...

Pour plus d'informations sur la technologie impliquée ...

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

Spring Boot est une solution prête à l’emploi et fonctionnelle pour les propriétés de configuration type-safe .

Décidément, utiliser Spring uniquement pour cette tâche est excessif, mais Spring propose de nombreuses fonctionnalités intéressantes et celle-ci peut vous attirer du côté droit;)

3
Andrew Kolpakov

Vous pouvez définir vos paramètres configurables comme "statiques" dans la classe de votre choix et, à partir d'un init statique, appeler une méthode qui charge les valeurs de paramètre à partir d'un fichier de propriétés. 

Par exemple:

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