युद्ध के बाहर जेएसएफ संदेश बंडल कैसे डालें?
दो तरीके:
Add its path to the runtime classpath of the server।
Create a custom ResourceBundle
implementation with a Control
।
पाठ परिवर्तन और आवेदन
टेक्स्ट को बदलने तुच्छ हो जाएगा पुनः आरंभ करने के बिना आवेदन में संदेशों को ताज़ा करें। हालांकि, ताज़ा करना तुच्छ नहीं है। Mojarra आंतरिक रूप से इसे आक्रामक रूप से कैश करता है। अगर आप रास्ते में जाना चाहते हैं तो इसे ध्यान में रखना होगा 1. अर्जुन तिजम्स ने इस संबंधित प्रश्न में अपने आंतरिक संसाधन बंडल कैश को साफ़ करने के लिए एक मोज़रा विशिष्ट चाल पोस्ट की है: How to reload resource bundle in web application?
यदि टेक्स्ट बदलना वेबैप में होता है स्वयं, तो आप बस सहेजने के तरीके में कैश क्लीनअप कर सकते हैं। हालांकि पाठ बदलने बाह्य हो सकता है, तो आप एक file system watch service रजिस्टर करने के लिए किसी भी तरह से 1 स्पष्ट बंडल कैश के लिए, या के लिए जिस तरह से 2 पुनः लोड आंतरिक handleGetObject()
में परिवर्तन (tutorial here) और फिर पर सुनने की जरूरत होगी।
युद्ध के भीतर एक डिफ़ॉल्ट बंडल, जो युद्ध में बाहरी बंडल द्वारा ओवरराइट है
जब उन्हें classpath से लोड हो रहा है, तो डिफ़ॉल्ट रूप इसका उल्टा है (संसाधन हैं उच्च वर्गीकरण प्राथमिकता है), इसलिए यह निश्चित रूप से रास्ता 1 को खरोंच करता है और हमें 2 तरीके से छोड़ देता है।
नीचे 2 का किकऑफ उदाहरण है। यह मानता है कि आप संपत्ति संसाधन बुन का उपयोग कर रहे हैं text
के आधार नाम के साथ डेल (यानी। कोई पैकेज नहीं) और बाहरी पथ /var/webapp/i18n
में स्थित है।
public class YourBundle extends ResourceBundle {
protected static final Path EXTERNAL_PATH = Paths.get("/var/webapp/i18n");
protected static final String BASE_NAME = "text";
protected static final Control CONTROL = new YourControl();
private static final WatchKey watcher;
static {
try {
watcher = EXTERNAL_PATH.register(FileSystems.getDefault().newWatchService(), StandardWatchEventKinds.ENTRY_MODIFY);
} catch (IOException e) {
throw new ExceptionInInitializerError(e);
}
}
private Path externalResource;
private Properties properties;
public YourBundle() {
Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
setParent(ResourceBundle.getBundle(BASE_NAME, locale, CONTROL));
}
private YourBundle(Path externalResource, Properties properties) {
this.externalResource = externalResource;
this.properties = properties;
}
@Override
protected Object handleGetObject(String key) {
if (properties != null) {
if (!watcher.pollEvents().isEmpty()) { // TODO: this is naive, you'd better check resource name if you've multiple files in the folder and keep track of others.
synchronized(properties) {
try (InputStream input = new FileInputStream(externalResource.toFile())) {
properties.load(input);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
return properties.get(key);
}
return parent.getObject(key);
}
@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public Enumeration<String> getKeys() {
if (properties != null) {
Set keys = properties.keySet();
return Collections.enumeration(keys);
}
return parent.getKeys();
}
protected static class YourControl extends Control {
@Override
public ResourceBundle newBundle
(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException
{
String resourceName = toResourceName(toBundleName(baseName, locale), "properties");
Path externalResource = EXTERNAL_PATH.resolve(resourceName);
Properties properties = new Properties();
try (InputStream input = loader.getResourceAsStream(resourceName)) {
properties.load(input); // Default (internal) bundle.
}
try (InputStream input = new FileInputStream(externalResource.toFile())) {
properties.load(input); // External bundle (will overwrite same keys).
}
return new YourBundle(externalResource, properties);
}
}
}
ताकि इसे चलाने रजिस्टर faces-config.xml
में नीचे के रूप में करने के लिए प्राप्त करने के लिए।
<application>
<resource-bundle>
<base-name>com.example.YourBundle</base-name>
<var>i18n</var>
</resource-bundle>
</application>
क्या यह सहायक है? http://stackoverflow.com/q/4499732 – BalusC
@ बाल्लूसी वैसे, जब पहले से ठोकर खा रहा है, तो सवाल के विवरण में नहीं देखा गया है, क्योंकि यह डेटाबेस के माध्यम से इसे संभालने का संदर्भ देता है, जो मेरे पास नहीं है - लेकिन मुझे लगता है आप 'संसाधन बंडल' को विस्तारित करने के हिस्से का जिक्र कर रहे हैं? तो 'getItSomehow'part में इसे फ़ाइल ऑपरेशन के माध्यम से लोड किया जाना चाहिए? उस स्थिति में यह इसे संभालने का एक तरीका हो सकता है। केवल दो वैकल्पिक आवश्यकताएं यहां शामिल होने के लिए स्पष्ट नहीं हैं। –
@ बाल्लूसी ओके, 2) समझ में आता है, 1) शायद गलत समझा जा सकता है - मुझे फ़ाइल में बदलावों को प्रतिबिंबित करने की आवश्यकता नहीं है, लेकिन फ़ाइल को बदलने में सक्षम हो और फिर बंडल का पुनः लोड ट्रिगर करें। - यदि आप टिप्पणी को उत्तर में रखने के लिए समय बिताना चाहते हैं, तो मुझे बक्षीस सौंपने में खुशी होगी। –