Gibt es eine Möglichkeit, über eine Java Bean auf web.xml-Eigenschaften zuzugreifen?

StackOverflow https://stackoverflow.com/questions/41659

  •  09-06-2019
  •  | 
  •  

Frage

Gibt es in der Servlet-API eine Möglichkeit, von einer Bean- oder Factory-Klasse aus, die überhaupt nicht mit dem Webcontainer verknüpft ist, auf die in web.xml angegebenen Eigenschaften (z. B. Initialisierungsparameter) zuzugreifen?

Ich schreibe beispielsweise eine Factory-Klasse und möchte eine Logik in die Factory einbinden, um eine Hierarchie von Dateien und Konfigurationsspeicherorten zu überprüfen, um festzustellen, welche ggf. verfügbar sind, um zu bestimmen, welche Implementierungsklasse instanziiert werden soll – zum Beispiel:

  1. eine Eigenschaftendatei im Klassenpfad,
  2. ein web.xml-Parameter,
  3. eine Systemeigenschaft, oder
  4. eine Standardlogik, wenn nichts anderes verfügbar ist.

Ich möchte dies tun können, ohne einen Verweis darauf einzufügen ServletConfig oder etwas Ähnliches wie meine Factory – der Code sollte außerhalb eines Servlet-Containers einwandfrei laufen können.

Das klingt vielleicht etwas ungewöhnlich, aber ich möchte, dass diese Komponente, an der ich arbeite, mit einer unserer Webanwendungen gepackt werden kann und außerdem vielseitig genug ist, um mit einigen unserer Befehlszeilentools ohne gepackt zu werden Da ich nur für meine Komponente eine neue Eigenschaftendatei benötige, hatte ich gehofft, auf andere Konfigurationsdateien wie web.xml zurückgreifen zu können.

Wenn ich mich richtig erinnere, hat .NET so etwas wie Request.GetCurrentRequest() um einen Verweis auf die aktuell ausgeführte Datei zu erhalten Request - Aber da es sich um eine Java-App handelt, suche ich nach etwas Ähnlichem, mit dem ich Zugriff erhalten könnte ServletConfig.

War es hilfreich?

Lösung

Eine Möglichkeit, dies zu tun, ist:

public class FactoryInitialisingServletContextListener implements ServletContextListener {

    public void contextDestroyed(ServletContextEvent event) {
    }

    public void contextInitialized(ServletContextEvent event) {
        Properties properties = new Properties();
        ServletContext servletContext = event.getServletContext();
        Enumeration<?> keys = servletContext.getInitParameterNames();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            String value = servletContext.getInitParameter(key);
            properties.setProperty(key, value);
        }
        Factory.setServletContextProperties(properties);
    }
}

public class Factory {

    static Properties _servletContextProperties = new Properties();

    public static void setServletContextProperties(Properties servletContextProperties) {
        _servletContextProperties = servletContextProperties;
    }
}

Und dann haben Sie Folgendes in Ihrer web.xml

<listener>
    <listener-class>com.acme.FactoryInitialisingServletContextListener<listener-class>
</listener>

Wenn Ihre Anwendung in einem Webcontainer ausgeführt wird, wird der Listener vom Container aufgerufen, sobald der Kontext erstellt wurde.In diesem Fall werden die _servletContextProperties durch alle in web.xml angegebenen Kontextparameter ersetzt.

Wenn Ihre Anwendung außerhalb eines Webcontainers ausgeführt wird, ist _servletContextProperties leer.

Andere Tipps

Haben Sie darüber nachgedacht, hierfür das Spring-Framework zu verwenden?Auf diese Weise bekommen Ihre Bohnen keine zusätzliche Kruft und Spring übernimmt die Konfigurationseinrichtung für Sie.

Ich denke, dass Sie eine zugehörige Bootstrap-Klasse hinzufügen müssen, die einen Verweis auf eine ServletConfig (oder einen ServletContext) entgegennimmt und diese Werte in die Factory-Klasse überträgt.Zumindest können Sie es so separat verpacken.

@toolkit:Ausgezeichnet, sehr demütig – das ist etwas, was ich schon seit einiger Zeit versuche

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top