Mysql
 sql >> Datenbank >  >> RDS >> Mysql

So laden Sie Werte dynamisch in die Kontext-XML-Datei von Tomcat

Angenommen, Sie haben eine tomcat/conf/context.xml-Datei, die etwa so aussieht:

<?xml version="1.0" encoding="utf-8"?>
<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <Resource 
            name="jdbc/MyDB" 
            auth="Container" 
            type="javax.sql.DataSource" 
            removeAbandoned="true" 
            removeAbandonedTimeout="15" 
            maxActive="5" 
            maxIdle="5" 
            maxWait="7000" 
            username="${db.mydb.uid}"
            password="${db.mydb.pwd}"
            driverClassName="${db.mydb.driver}"
            url="${db.mydb.url}${db.mydb.dbName}?autoReconnectForPools=true&amp;characterEncoding=UTF-8"
            factory="com.mycompany.util.configuration.CustomDataSourceFactory"
            validationQuery="SELECT '1';"
            testOnBorrow="true"/>
</Context>

Was wir in diesem Fall ersetzen möchten, ist alles im ${.*}-Zeug in dieser Ressourcendefinition. Mit einer geringfügigen Änderung des unten stehenden Codes können Sie diese Ersetzungen jedoch für so ziemlich alle gewünschten Kriterien durchführen.

Beachten Sie die Zeile factory="com.mycompany.util.configuration.CustomDataSourceFactory"

Dies bedeutet, dass Tomcat versuchen wird, diese Factory zu verwenden, um diese Ressource zu verarbeiten. Es sollte erwähnt werden, dass dies bedeutet, dass sich diese Factory beim Start auf dem Klassenpfad von Tomcat befinden muss (persönlich habe ich meine in ein JAR in der lib von Tomcat eingefügt Verzeichnis).

So sieht meine Fabrik aus:

package com.mycompany.util.configuration;

import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.StringRefAddr;
import javax.naming.spi.ObjectFactory;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class CustomDataSourceFactory extends BasicDataSourceFactory implements ObjectFactory {

    private static final Pattern _propRefPattern = Pattern.compile("\\$\\{.*?\\}");

    //http://tomcat.apache.org/tomcat-6.0-doc/jndi-resources-howto.html#Adding_Custom_Resource_Factories
    @Override
    public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws Exception {
        if (obj instanceof Reference) {
            Reference ref = (Reference) obj;
            System.out.println("Resolving context reference values dynamically");

            for(int i = 0; i < ref.size(); i++) {
                RefAddr addr = ref.get(i);
                String tag = addr.getType();
                String value = (String) addr.getContent();

                Matcher matcher = _propRefPattern.matcher(value);
                if (matcher.find()) {
                    String resolvedValue = resolve(value);
                    System.out.println("Resolved " + value + " to " + resolvedValue);
                    ref.remove(i);
                    ref.add(i, new StringRefAddr(tag, resolvedValue));
                }
            }
        }
        // Return the customized instance
        return super.getObjectInstance(obj, name, nameCtx, environment);
    }

    private String resolve(String value) {
        //Given the placeholder, do stuff to figure out what it's true value should be, and return that String.
        //This could be decryption, or maybe using a properties file.
    }
}

Sobald sich dieser Code im Klassenpfad befindet, starten Sie Tomcat neu und beobachten Sie catalina.out auf die Protokollmeldungen. HINWEIS:Das System.out.println -Anweisungen werden wahrscheinlich vertrauliche Informationen in Ihre Protokolle schreiben, daher möchten Sie sie möglicherweise entfernen, sobald Sie mit dem Debuggen fertig sind.

Als Nebenbemerkung habe ich dies aufgeschrieben, weil ich fand, dass viele Beispiele zu spezifisch für ein bestimmtes Thema waren (z. B. die Verwendung von Kryptografie), und ich wollte zeigen, wie dies allgemein gemacht werden kann. Darüber hinaus erklären sich einige der anderen Antworten auf diese Frage nicht sehr gut, und ich musste etwas graben, um herauszufinden, was getan werden musste, damit diese Arbeit funktioniert. Ich wollte meine Erkenntnisse mit euch teilen. Bitte zögern Sie nicht, dies zu kommentieren, Fragen zu stellen oder Korrekturen vorzunehmen, wenn Sie Probleme finden, und ich werde die Korrekturen auf jeden Fall in meine Antwort einfließen lassen.