sql >> Database >  >> RDS >> Mysql

Hoe dynamisch waarden in Tomcat's Context XML-bestand te laden

Stel dat je een tomcat/conf/context.xml-bestand hebt dat er ongeveer zo uitziet:

<?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>

Wat we in dit geval willen vervangen, is alles in de ${.*} dingen in deze resourcedefinitie. Met een kleine wijziging in de onderstaande code kunt u deze vervangingen echter op vrijwel elke gewenste criteria uitvoeren.

Let op de regel factory="com.mycompany.util.configuration.CustomDataSourceFactory"

Dit betekent dat Tomcat zal proberen deze fabriek te gebruiken om deze bron te verwerken. Er moet worden vermeld dat dit betekent dat deze fabriek bij het opstarten op Tomcat's klassenpad moet staan ​​(persoonlijk plaats ik de mijne in een JAR in de Tomcat lib adresboek).

Zo ziet mijn fabriek eruit:

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.
    }
}

Als deze code eenmaal op het klassenpad staat, start u Tomcat opnieuw en kijkt u naar catalina.out voor de logberichten. OPMERKING:De System.out.println verklaringen zullen waarschijnlijk gevoelige informatie naar uw logbestanden afdrukken, dus u kunt ze verwijderen zodra u klaar bent met debuggen.

Even terzijde, ik heb dit opgeschreven omdat ik vond dat veel voorbeelden te specifiek waren voor één specifiek onderwerp (zoals het gebruik van cryptografie), en ik wilde laten zien hoe dit generiek kan worden gedaan. Bovendien verklaren sommige van de andere antwoorden op deze vraag zichzelf niet zo goed, en ik moest wat graven om erachter te komen wat er moest gebeuren om dit te laten werken. Ik wilde mijn bevindingen met jullie delen. Voel je vrij om hier commentaar op te geven, vragen te stellen of correcties aan te brengen als je problemen tegenkomt, en ik zal de oplossingen zeker in mijn antwoord opnemen.



  1. Aangepaste datum-/tijdnotatie in SQL Server

  2. MySQL selecteert records voor duplicaten met meerdere kolommen

  3. Databaserecords groeperen in tijdsintervallen van 15 minuten

  4. Postgres - Aangrenzende lijst converteren naar genest JSON-object