Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak dynamicznie ładować wartości do pliku XML kontekstu Tomcata

Załóżmy, że masz plik tomcat/conf/context.xml, który wygląda mniej więcej tak:

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

W tym przypadku chcemy zastąpić wszystko, co zawiera ${.*} w tej definicji zasobu. Jednak po niewielkich modyfikacjach poniższego kodu możesz wykonać te zamiany na praktycznie dowolnych kryteriach.

Zwróć uwagę na wiersz factory="com.mycompany.util.configuration.CustomDataSourceFactory"

Oznacza to, że Tomcat spróbuje użyć tej fabryki do przetworzenia tego zasobu. Należy wspomnieć, że oznacza to, że ta fabryka będzie musiała znajdować się na ścieżce klas Tomcata podczas uruchamiania (osobiście umieściłem swoją w JAR w lib Tomcata informator).

Oto jak wygląda moja fabryka:

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

Następnie, gdy ten kod znajdzie się w ścieżce klasy, uruchom ponownie Tomcata i obserwuj catalina.out w poszukiwaniu komunikatów dziennika. UWAGA:System.out.println wyciągi prawdopodobnie spowodują wydrukowanie poufnych informacji w dziennikach, więc możesz chcieć je usunąć po zakończeniu debugowania.

Na marginesie napisałem to, ponieważ odkryłem, że wiele przykładów było zbyt specyficznych dla jednego konkretnego tematu (takiego jak wykorzystanie kryptografii) i chciałem pokazać, jak można to zrobić ogólnie. Co więcej, niektóre inne odpowiedzi na to pytanie nie wyjaśniają się zbyt dobrze i musiałem trochę kopać, aby dowiedzieć się, co należy zrobić, aby to zadziałało. Chciałem podzielić się z wami moimi odkryciami. Zachęcamy do komentowania tego, zadawania jakichkolwiek pytań lub wprowadzania poprawek, jeśli znajdziesz problemy, a na pewno wprowadzę poprawki do mojej odpowiedzi.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lepsze zrozumienie — Class.forName(com.mysql.jdbc.Driver).newInstance ();

  2. PHP i MySQL opcjonalne warunki WHERE

  3. MySQL:uśrednianie z wartościami null

  4. Wyświetlanie wartości bazy danych zgodnie z wybranym filtrem w menu rozwijanym

  5. Niestandardowa nazwa identyfikatora SailsJS i mySQL nie działa z niebieskimi wydrukami