Řekněme, že máte soubor tomcat/conf/context.xml, který vypadá asi takto:
<?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>
V tomto případě chceme nahradit cokoli z ${.*} v této definici zdroje. S mírnou úpravou níže uvedeného kódu však můžete tyto substituce provádět téměř podle jakýchkoli kritérií, která chcete.
Všimněte si řádku factory="com.mycompany.util.configuration.CustomDataSourceFactory"
To znamená, že Tomcat se pokusí použít tuto továrnu ke zpracování tohoto zdroje. Je třeba zmínit, že to znamená, že tato továrna bude muset být při spuštění na cestě ke třídě Tomcatu (Osobně jsem svůj vložil do JAR v Tomcat lib
adresář).
Moje továrna vypadá takto:
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.
}
}
Poté, jakmile je tento kód na cestě třídy, restartujte Tomcat a sledujte catalina.out pro zprávy protokolu. POZNÁMKA:Soubor System.out.println
příkazy pravděpodobně skončí tiskem citlivých informací do vašich protokolů, takže je možná budete chtít po dokončení ladění odstranit.
Na okraj jsem to napsal, protože jsem zjistil, že mnoho příkladů bylo příliš specifických pro jedno konkrétní téma (jako je použití kryptografie), a chtěl jsem ukázat, jak to lze udělat obecně. Kromě toho některé další odpovědi na tuto otázku se samy nevysvětlují příliš dobře a musel jsem trochu pátrat, abych zjistil, co je potřeba udělat, aby to fungovalo. Chtěl jsem se s vámi podělit o své poznatky. Neváhejte se k tomu vyjádřit, zeptejte se nebo proveďte opravy, pokud narazíte na problémy, a já určitě zapracuji opravy do své odpovědi.