web-dev-qa-db-fra.com

Charger Java propriétés dans le bloc d'initialisation statique

J'ai une classe util statique qui manipule des chaînes sur des données un peu sensibles. Avant d'utiliser cette classe, je dois initialiser certaines variables statiques avec des valeurs, telles que les noms d'utilisateur/mot de passe, que je préfère stocker dans un .properties fichier.

Je ne sais pas très bien comment le chargement de .properties fichier fonctionne en Java, en particulier en dehors du conteneur * Spring DI *. N'importe qui peut me donner un coup de main/un aperçu de la façon dont cela peut être fait?

Je vous remercie!

Ajout:.properties l'emplacement précis du fichier est inconnu, mais il sera sur le chemin des classes. Sorta comme classpath:/my/folder/name/myproperties.propeties

21
xelurg

Tout d'abord, obtenez un InputStream à partir duquel les propriétés doivent être chargées. Cela peut provenir d'un certain nombre d'endroits, y compris certains des plus probables:

  • A FileInputStream , créé avec un nom de fichier codé en dur ou spécifié via propriété système. Le nom peut être relatif (par rapport au répertoire de travail actuel du Java processus) ou absolu.
  • Un fichier de ressources (un fichier sur le chemin de classe), obtenu par un appel à getResourceAsStream sur Class (par rapport au fichier de classe) ou ClassLoader (par rapport à la racine du chemin de classe). Notez que ces méthodes renvoient null si la ressource est manquante, au lieu de déclencher une exception.
  • A URL , qui, comme un nom de fichier, peut être codé en dur ou spécifié via une propriété système.

Créez ensuite un nouvel objet Properties et passez le InputStream à sa méthode load() . Assurez-vous de fermer le flux, quelles que soient les exceptions.

Dans un initialiseur de classe, les exceptions vérifiées telles que IOException doivent être gérées. Une exception non vérifiée peut être levée, ce qui empêchera la classe d'être initialisée. Cela, à son tour, empêchera généralement votre application de s'exécuter. Dans de nombreuses applications, il peut être souhaitable d'utiliser les propriétés par défaut à la place, ou de revenir à une autre source de configuration, par exemple en demandant une utilisation dans un contexte interactif.

Au total, cela pourrait ressembler à ceci:

private static final String NAME = "my.properties";

private static final Properties config;

static {
  Properties fallback = new Properties();
  fallback.put("key", "default");
  config = new Properties(fallback);

  URL res = MyClass.getResource(NAME);
  if (res == null) throw new UncheckedIOException(new FileNotFoundException(NAME));
  URI uri;
  try { uri = res.toURI(); }
  catch (URISyntaxException ex) { throw new IllegalArgumentException(ex); }

  try (InputStream is = Files.newInputStream(Paths.get(uri))) { config.load(is); } 
  catch (IOException ex) { throw new UncheckedIOException("Failed to load resource", ex); }
}
29
erickson
  1. Vérifiez Java.util.Properties .

  2. Vous pouvez utiliser un initialiseur statique. Donc, en haut de la classe, vous pouvez faire:


 static {
    Properties props = new Properties();
    InputStream Steam = ...; // open the file
    props.load(stream);

    // process properties content
    String username = props.getProperty("username");
  }
6
notnoop

Utilisez soit:

CurrentClassName.class.getResourceAsStream 
new FileInputStream(File)

pour obtenir le flux d'entrée selon que la classe est dans ou hors du chemin de classe. Ensuite, utilisez

Properties.load

pour charger les propriétés.

3
stevedbrown

Cela fait un moment, mais si je me souviens bien, vous faites quelque chose comme ceci:

Properties prop = new Properties();
prop.load(new FileInputStream(filename));

//For each property you need.
blah = prop.getProperty(propertyname);
2
patros

pour moi, MyClass.class.getClassLoader().getResourceAsStream(..) a fait l'affaire:

private static final Properties properties;

static {
    Properties fallback = new Properties();
    fallback.put(PROP_KEY, FALLBACK_VALUE);

    properties = new Properties(fallback);

    try {
        try (InputStream stream = MyClass.class.getClassLoader().getResourceAsStream("myProperties.properties")) {
            properties.load(stream);
        }
    } catch (IOException ex) {
        // handle error
    }
}
1
electrobabe

Eh bien, avec les propriétés statiques, il serait logique de les initialiser en tant que Singleton qui sera chargé une fois dans une classe. Voici un exemple:

class Example
{
    public final static String PROPSFILE = "test.properties";

    private static Properties props;

    protected static Properties getProperties()
    {
        if(props == null)
        {
            props = new Properties();
            props.load(new FileInputStream(new File(PROPSFILE));
        }
        return props;
    }

    public static User getUser()
    {
        String username = getProperties().getProperty("username");
        return new User(username);
    }
}

Si vous utilisez des chemins relatifs, vous devez vous assurer que votre chemin de classe est correctement configuré.

1
Daff

Je suis d'accord avec @Daff, il vaut peut-être mieux utiliser la classe singleton ... c'est ce que j'ai sur mon projet pour une exigence similaire, peut-être que cela peut aider:

les clients de la classe peuvent l'utiliser comme ceci:

ConfigsLoader configsLoader = ConfigsLoader.getInstance("etc/configs.xml");

System.out.format("source dir %s %n", configsLoader.getSourceDir());

puis la classe:

public class ConfigsLoader {

private String sourceDir;
private String destination;
private String activeMqUrl;

private static Logger log = Logger.getLogger(ConfigsLoader.class.getName());

private static ConfigsLoader instance = null;

private ConfigsLoader(String configFileName) {
    log.info("loading configs");
    Properties configs = new Properties();
    try {
        configs.loadFromXML(new FileInputStream(configFileName));

        sourceDir = configs.getProperty("source.dir");
        destination = configs.getProperty("destination");
        activeMqUrl = configs.getProperty("activemqconnectionurl");
        configs.setProperty("lastLoaded", new SimpleDateFormat("yyyy-M-d HH:mm").format(new Date()));
        configs.storeToXML(new FileOutputStream(configFileName), "saving last modified dates");

    } catch (InvalidPropertiesFormatException e) {
        log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
    } catch (FileNotFoundException e) {
        log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
    } catch (IOException e) {
        log.log(Level.SEVERE,"Error occured loading the properties file" ,e);
    }
}

public static ConfigsLoader getInstance(String configFileName) {
    if(instance ==null) {
        instance = new ConfigsLoader(configFileName);
    }

    return instance;
}

public String getSourceDir() {
    return sourceDir;
}

public void setSourceDir(String sourceDir) {
    this.sourceDir = sourceDir;
}

public String getDestination() {
    return destination;
}

public void setDestination(String destination) {
    this.destination = destination;
}

public String getActiveMqUrl() {
    return activeMqUrl;
}

public void setActiveMqUrl(String activeMqUrl) {
    this.activeMqUrl = activeMqUrl;
}

}

0
Mosd

J'ai finalement fait cela en utilisant la fonction getResourceAsStream () associée à la classe dans laquelle le bloc de code statique est écrit.

//associate Property and ImputStream imports
public class A {
    static Properties p;
    static {
      p = new Properties();
      try {
          InputStream in = A.class.getResourceAsStream("filename.properties");
          p.load(in);
      } catch (FileNotFoundException e) {
        System.out.println("FileNotFoundException");
        e.printStackTrace();
      } catch (IOException e) {
        System.out.println("IOException");
        e.printStackTrace();
      }
    }
    .
    .
    .
}
0
kung_fu_coder