2010-09-05 16 views
9

में यूटीएफ -8 एन्कोडेड गुण फ़ाइलों के साथ i18n मैं jsf-ri 2.0.3 का उपयोग कर रहा हूं जहां हिब्रू और रूसी समर्थन की आवश्यकता है। समस्या यह है कि मैं सही पाठ की बजाय स्क्रीन पर अस्पष्टता देखता हूं।i18n जेएसएफ 2.0 अनुप्रयोग

सबसे पहले मैंने प्रत्येक भाषा के लिए बंडल (* _locale.properties) परिभाषित किया है। फाइलें यूटीएफ -8 एन्कोडिंग में हैं। चेहरे-config.xml

<locale-config> 
    <default-locale>iw</default-locale> 
    <supported-locale>en</supported-locale> 
    <supported-locale>ru</supported-locale> 
</locale-config> 

से मुझे लगता है कि UTF-8 के जवाब charcter एन्कोडिंग सेट हो जाएगा कस्टम फ़िल्टर जोड़ दिया है में दूसरे, मैं डिफ़ॉल्ट परिभाषित और समर्थित किया है स्थानों।

<filter> 
    <filter-name>encodingFilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
    <init-param> 
     <param-name>encoding</param-name> 
     <param-value>UTF-8</param-value> 
    </init-param> 
    <init-param> 
     <param-name>forceEncoding</param-name> 
     <param-value>true</param-value> 
    </init-param> 
</filter> 
<filter-mapping> 
    <filter-name>encodingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
</filter-mapping> 

और अंत में जब मैं उत्पादन मैं एक बहुत ही अजीब परिणाम देखने डिबग करने के लिए एक सरल एक्सएचटीएमएल बनाने

<f:loadBundle basename="i18n.frontend.homepage" var="msg"/> 
<strong>i18n: </strong><h:outputText value="#{msg.language}"/> 
<br/> 
<strong>Locale: </strong> 
<h:outputText value="#{facesContext.externalContext.response.locale}"/> 
<br/> 
<strong>Encoding: </strong> 
<h:outputText value="#{facesContext.externalContext.response.characterEncoding}"/> 

परिणाम है:

i18n: ×¢×ר×ת 
Locale: en_US 
Encoding: UTF-8 

क्या मेरी विन्यास के साथ गलत क्या है?

उत्तर

22

ठीक है, आप एक कस्टम ResourceBundle बना सकते हैं या native2ascii कनवर्टर (यदि आवश्यक हो तो Maven 2 प्लगइन के साथ रूपांतरण को अधिक पारदर्शी बनाने के लिए) का उपयोग कर सकते हैं:

यहाँ विन्यास उदाहरण है। चूंकि दूसरा उत्तर केवल अंतिम दृष्टिकोण के साथ विस्तार से जाता है, यहां एक और जवाब है कि आप जावा एसई 1.6 आधारित पर्यावरण पर जेएसएफ 2.x एप्लिकेशन में यूटीएफ -8 के रूप में गुण फ़ाइलों को लोड करने के लिए एक कस्टम ResourceBundle कैसे बना सकते हैं।

faces-config.xml

<application> 
    <resource-bundle> 
     <base-name>com.example.i18n.Text</base-name> 
     <var>text</var> 
    </resource-bundle> 
</application> 

com.example.i18n.Text

package com.example.i18n; 

import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.URL; 
import java.net.URLConnection; 
import java.util.Enumeration; 
import java.util.Locale; 
import java.util.PropertyResourceBundle; 
import java.util.ResourceBundle; 

import javax.faces.context.FacesContext; 

public class Text extends ResourceBundle { 

    protected static final String BUNDLE_NAME = "com.example.i18n.text"; 
    protected static final String BUNDLE_EXTENSION = "properties"; 
    protected static final String CHARSET = "UTF-8"; 
    protected static final Control UTF8_CONTROL = new UTF8Control(); 

    public Text() { 
     setParent(ResourceBundle.getBundle(BUNDLE_NAME, 
      FacesContext.getCurrentInstance().getViewRoot().getLocale(), UTF8_CONTROL)); 
    } 

    @Override 
    protected Object handleGetObject(String key) { 
     return parent.getObject(key); 
    } 

    @Override 
    public Enumeration<String> getKeys() { 
     return parent.getKeys(); 
    } 

    protected static class UTF8Control extends Control { 
     public ResourceBundle newBundle 
      (String baseName, Locale locale, String format, ClassLoader loader, boolean reload) 
       throws IllegalAccessException, InstantiationException, IOException 
     { 
      // The below code is copied from default Control#newBundle() implementation. 
      // Only the PropertyResourceBundle line is changed to read the file as UTF-8. 
      String bundleName = toBundleName(baseName, locale); 
      String resourceName = toResourceName(bundleName, BUNDLE_EXTENSION); 
      ResourceBundle bundle = null; 
      InputStream stream = null; 
      if (reload) { 
       URL url = loader.getResource(resourceName); 
       if (url != null) { 
        URLConnection connection = url.openConnection(); 
        if (connection != null) { 
         connection.setUseCaches(false); 
         stream = connection.getInputStream(); 
        } 
       } 
      } else { 
       stream = loader.getResourceAsStream(resourceName); 
      } 
      if (stream != null) { 
       try { 
        bundle = new PropertyResourceBundle(new InputStreamReader(stream, CHARSET)); 
       } finally { 
        stream.close(); 
       } 
      } 
      return bundle; 
     } 
    } 
} 

यह उम्मीद text.properties, text_en.properties, com.example.i18n पैकेज में आदि जैसे UTF-8 एन्कोडेड गुण फ़ाइलें। देशी 2ascii के लिए कोई ज़रूरत नहीं है।

वैसे, नई जेएसएफ 2.0 शैली <resource-bundle>faces-config.xml में घोषणा के साथ, आपको अब दृश्यों में <f:loadBundle> की आवश्यकता नहीं है। सभी पाठ सीधे सभी दृश्यों में #{text} द्वारा उपलब्ध होंगे।

+0

यह एक शानदार उपकरण है। क्या इसे कुछ दिनों में ओमनीफेस में जोड़ा जाएगा? – Med

+1

@ मेड: मैंने यह माना है, लेकिन मैंने फैसला किया कि यह "हैकी" के किनारे पर है। इसके बजाय सही संपादकों का उपयोग करें और ईक्लीप्स और/या मेवेन/चींट जैसे टूल बनाएं। उदा।, ग्रहण के अंतर्निहित गुण फ़ाइल संपादक का उपयोग करते समय, यूटीएफ -8 को पारदर्शी रूप से आईएसओ -885 9 -1 के रूप में सहेज लिया जाएगा जहां आवश्यक हो वहां यूनिकोड कोडपॉइंट्स के साथ। – BalusC

+0

ठीक है, मुझे तुम्हारा मुद्दा मिला! धन्यवाद। – Med

3

ठीक है, एक गहरी जांच के बाद मुझे समाधान मिला है।

जावा 1.6 PropertyResourceBundle को

इससे पहले केवल एक निर्माता जो निम्नलिखित प्रलेखन The property file read with this constructor must be encoded in ISO-8859-1. है इसका मतलब यह है कि यह संसाधन बंडलों में केवल अंग्रेजी पाठ का उपयोग करना संभव है था।

पहले एक एक कस्टम loadBundle घटक जो सही ResourceBundle इन्स्टेन्शियशन विधि का उपयोग करेगा लिख ​​रहा है:

इस समस्या के लिए दो समाधान कर रहे हैं।

दूसरा (मेरी पसंद) Native-to-ASCII कनवर्टर का उपयोग कर रहा है जिसका उपयोग Native2Ascii maven plugin का उपयोग करके मेवेन के साथ किया जा सकता है।

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>native2ascii-maven-plugin</artifactId> 
    <executions> 
     <execution> 
      <goals> 
       <goal>native2ascii</goal> 
      </goals> 
      <configuration> 
       <src>${basedir}/src/main/resources</src>     
       <dest>${project.build.directory}/native2ascii</dest> 
       <encoding>UTF8</encoding> 
       <includes>**/*.properties</includes> 
      </configuration> 
     </execution> 
    </executions> 
</plugin> 
0

मेरे पास स्टैंडअलोन एसडब्ल्यूटी एप्लीकेशन के साथ एक ही समस्या है। यह विंडोबिल्डर द्वारा उत्पन्न संशोधित संसाधन लोडर है। मूलभूत विचार - संदेश वर्ग में केवल स्ट्रिंग फ़ील्ड में संसाधन होते हैं। इसलिए कच्चे आईएसओ -885 9 -1 लोडिंग के बाद मैं उन्हें यूटीएफ 8 (यदि संभव हो) में परिवर्तित कर देता हूं।

import java.lang.reflect.Field; 

import org.eclipse.osgi.util.NLS; 

public class Messages extends NLS { 
private static final String BUNDLE_NAME = "org.digimead.tabuddy.desktop.res.messages"; //$NON-NLS-1$ 
public static String MainWindow_newShell_text; 
public static String MainWindow_actionOpenFile_text; 
public static String MainWindow_actionCloseFile_text; 

// ////////////////////////////////////////////////////////////////////////// 
// 
// Constructor 
// 
// ////////////////////////////////////////////////////////////////////////// 
private Messages() { 
    // do not instantiate 
} 

// ////////////////////////////////////////////////////////////////////////// 
// 
// Class initialization 
// 
// ////////////////////////////////////////////////////////////////////////// 
static { 
    // load message values from bundle file 
    NLS.initializeMessages(BUNDLE_NAME, Messages.class); 
    final Field[] fieldArray = Messages.class.getDeclaredFields(); 
    final int len = fieldArray.length; 
    for (int i = 0; i < len; i++) { 
     final Field field = (Field) fieldArray[i]; 
     if (field.getType() == java.lang.String.class) { 
      if (!field.isAccessible()) 
       field.setAccessible(true); 
      try { 
       final String rawValue = (String) field.get(null); 
       field.set(null, new String(rawValue.getBytes("ISO-8859-1"), 
         "UTF-8")); 
      } catch (Exception e) { 
       // skip field modification 
      } 
     } 
    } 
} 

}

संबंधित मुद्दे