मान लें कि आपके पास एक 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"
इसका मतलब यह है कि टॉमकैट इस संसाधन को संसाधित करने के लिए इस कारखाने का उपयोग करने का प्रयास करेगा। यह उल्लेख किया जाना चाहिए कि इसका मतलब है कि इस कारखाने को स्टार्टअप पर टॉमकैट के क्लासपाथ पर होना होगा (व्यक्तिगत रूप से, मैं टॉमकैट में एक जार में डालता हूं lib
निर्देशिका)।
यहाँ मेरा कारखाना कैसा दिखता है:
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.
}
}
फिर, एक बार यह कोड क्लासपाथ पर होने के बाद, टॉमकैट को पुनरारंभ करें और लॉग संदेशों के लिए catalina.out देखें। नोट:System.out.println
कथन संभवतः आपके लॉग में संवेदनशील जानकारी को प्रिंट कर देंगे, इसलिए डिबगिंग करने के बाद आप उन्हें हटाना चाह सकते हैं।
एक विचार पर, मैंने इसे लिखा क्योंकि मैंने पाया कि कई उदाहरण एक विशिष्ट विषय (जैसे क्रिप्टोग्राफी का उपयोग) के लिए बहुत विशिष्ट थे, और मैं यह दिखाना चाहता था कि यह सामान्य रूप से कैसे किया जा सकता है। इसके अलावा, इस प्रश्न के कुछ अन्य उत्तर खुद को बहुत अच्छी तरह से नहीं समझाते हैं, और मुझे यह पता लगाने के लिए कुछ खुदाई करनी पड़ी कि इस काम को करने के लिए क्या किया जाना चाहिए। मैं अपने निष्कर्ष आप लोगों के साथ साझा करना चाहता था। कृपया इस पर बेझिझक टिप्पणी करें, कोई प्रश्न पूछें, या यदि आपको समस्याएँ आती हैं तो सुधार करें, और मैं अपने उत्तर में सुधारों को शामिल करना सुनिश्चित करूँगा।