11 Stimmen

Programmgesteuerter Zugriff auf die Eigenschaftsdatei in einer JSF-Anwendung

Ich versuche, auf die i18n-Eigenschaften-Datei zuzugreifen, die ich in meiner JSF-Anwendung im Code verwende. (Die Idee ist, eine Seite zu haben, die ihre Schlüssel und Werte als eine Tabelle tatsächlich anzeigt).

Das Projekt ist ein Maven-Projekt und befindet sich im Ordner src/resources/localization, und wird in der War-Datei in WEB-INF bereitgestellt \classes\localization\

java.util.Properties prop = new java.util.Properties();
String path = "localization/stat_codes.properties";
InputStream foo = prop.getClass().getResourceAsStream(path);

Aber die Variable foo stellt sich als Null heraus, egal wie ich die Pfadvariable setze, /WEB-INF/classes/localization/stat_codes.properties, "localization.stat_codes.properties" usw. Eine ähnliche Frage ist aquí aber auch hier gibt es keine hilfreiche Antwort.

25voto

BalusC Punkte 1034465

En Class#getResourceAsStream() kann einen Pfad annehmen, der relativ zum Ort der Class die Sie dort als Ausgangspunkt verwenden. Wenn sich die Klasse also zum Beispiel im Verzeichnis com.example Paket und Sie fordern den Pfad foo/filename.properties dann wird es eigentlich Laden Sie die com/example/foo/filename.properties Datei. Aber wenn Sie die /foo/filename.properties dann wird es eigentlich laden foo/filename.properties aus dem Klassenpfad Root.

Also, Ihr Code

java.util.Properties prop = new java.util.Properties();
String path = "localization/stat_codes.properties";
InputStream foo = prop.getClass().getResourceAsStream(path);

wird eigentlich suchen java/util/localization/stat_codes.properties fichier.

Aber in Anwendungen mit einer komplexen Hierarchie von mehreren Classloadern ist der eine Classloader nicht der andere. Der Classloader, der die Kern-Java-Klassen geladen hat, hat nicht notwendigerweise Kenntnisse über die Dateien, die in der Webapp /WEB-INF/classes . Daher wird der Pfad mit dem Präfix / nicht zwangsläufig die Lösung sein wird, würde es immer noch null .

Wenn Sie garantieren können, dass die aktuelle Klasse vom gleichen Classloader wie die Eigenschaftsdateien sichtbar ist (weil sie sich im gleichen Unterverzeichnis des Klassenpfads befinden, z. B. /WEB-INF/classes verwenden, dann sollten Sie tatsächlich

String path = "/localization/stat_codes.properties";
InputStream foo = this.getClass().getResourceAsStream(path);

Wenn aber irgendwann die Eigenschaftsdateien wegen der einfacheren Wartung/Bearbeitung während der Laufzeit externalisiert werden, so dass Sie die Webapp nicht jedes Mal neu erstellen/verteilen/neustarten müssen, wenn Sie die Dateien bearbeiten wollen, dann wird die obige Codezeile wahrscheinlich ebenfalls fehlschlagen. Der ausgelagerte Speicherort wäre nur über einen anderen Classloader zugänglich. Die kanonische Lösung besteht darin, stattdessen den Kontext-Classloader des Threads als Startpunkt zu verwenden, der Zugriff hat auf tous Ressourcen im Klassenpfad.

String path = "localization/stat_codes.properties";
ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream foo = loader.getResourceAsStream(path);

(Beachten Sie, dass dieser nicht einen Pfad nehmen kann, der mit / Sie ist immer relativ zur gemeinsamen Wurzel)

Siehe auch:

1voto

ustun Punkte 6723

Es scheint, dass der Übeltäter die prop Objekt, ich nehme an, jedes Objekt würde funktionieren, aber es muss das aktuelle Objekt sein ( this ), auf dem die Methode getClass() aufgerufen wird, scheint es. Außerdem sollte der Pfad mit einem / da die localization Verzeichnis befindet sich in WEB-INF/classes .

String path = "localization/stat_codes.properties";
InputStream foo = this.getClass().getResourceAsStream(path);

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X