Да речем, че имате файл tomcat/conf/context.xml, който изглежда нещо подобно:
<?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&characterEncoding=UTF-8"
factory="com.mycompany.util.configuration.CustomDataSourceFactory"
validationQuery="SELECT '1';"
testOnBorrow="true"/>
</Context>
Това, което искаме да заменим в този случай, е всичко в ${.*} неща в тази дефиниция на ресурс. С лека модификация на кода по-долу обаче можете да извършите тези замествания по почти каквито критерии желаете.
Обърнете внимание на реда factory="com.mycompany.util.configuration.CustomDataSourceFactory"
Това означава, че Tomcat ще се опита да използва тази фабрика за обработка на този ресурс. Трябва да се спомене, че това означава, че тази фабрика ще трябва да бъде в пътя на класа на Tomcat при стартиране (Лично аз поставих моя в JAR в lib
на Tomcat директория).
Ето как изглежда моята фабрика:
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.
}
}
След това, след като този код е в пътя към класа, рестартирайте Tomcat и гледайте catalina.out за съобщенията в журнала. ЗАБЕЛЕЖКА:System.out.println
операторите вероятно ще отпечатат чувствителна информация във вашите регистрационни файлове, така че може да искате да ги премахнете, след като приключите с отстраняването на грешки.
В странична бележка написах това, защото открих, че много примери са твърде специфични за една конкретна тема (като използване на криптография) и исках да покажа как това може да се направи общо. Освен това, някои от другите отговори на този въпрос не се обясняват много добре и трябваше да се поразровя, за да разбера какво трябва да се направи, за да работи това. Исках да споделя своите открития с вас. Моля, не се колебайте да коментирате това, да задавате въпроси или да правите корекции, ако откриете проблеми, и аз със сигурност ще включа корекциите в моя отговор.