Как читать арабский или персидский (ключ и значения) из файла java с ResourceBundle

Я пытаюсь читать арабские и персидские ключи и значения из файла java вместо файла свойств с ResourceBundle, но он отображает неизвестные символы.

То, что я сделал, это то, что я закодировал 3 файла как:
1. LabelsBundle_en_US.Ява
2. LabelsBundle_ar_AE.Ява
3. LabelsBundle_fa_IR.Ява

My LabelsBundle_en_US.java файл выглядит как:

public class LabelsBundle_en_US extends ListResourceBundle{
            static final Object[][] contents = {
                                                {"REGISTER","Registration Form"},
                                                {"USERNAME","Email"},
                                                {"PASSWORD","Password"},
                                                {"CONFIRM_PASS","Confirm Password"},
                                                {"SUBMIT","Register"}
                                                };

            protected Object[][] getContents(){
            return contents;
            }   
    }//class

My LabelsBundle_fa_IR.java файл выглядит как:

public class LabelsBundle_fa_IR extends ListResourceBundle{
        static final Object[][] contents = {
                                            {"REGISTER","ثبت نام"},
                                            {"USERNAME","ایمیل"},
                                            {"PASSWORD","رمز"},
                                            {"CONFIRM_PASS","مرور رمز"},
                                            {"SUBMIT","ارسال"}
                                            };

        protected Object[][] getContents(){
        return contents;
        }   
}//class

Вот мой сервлет:

protected void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException{      
        res.setContentType("text/html; charset=UTF-8");
        req.setCharacterEncoding("UTF-8");
        res.setCharacterEncoding("UTF-8");      
        StringWriter sWriter    = new StringWriter();  
        PrintWriter out         = new PrintWriter(sWriter);         

        String country          = req.getParameter("country");
        String language         = req.getParameter("language");
        Locale locale=null;
        if(country == null){
            locale = new Locale("en","US");
        }
        else{
            locale = new Locale(language, country);
        }       
        ResourceBundle rb = ResourceBundle.getBundle("com.i18n.resource.bundles.LabelsBundle",locale);
        req.setAttribute("resource", rb);

        out.println("<?xml version="1.0" encoding="UTF-8"?>"+
                    "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">"+
                    "<html  content='text/html; charset=UTF-8' />"+
                    "<body>"+
                    "<center><h1>"+rb.getString("REGISTER")+"</h1></center>"+
                    "<table border=0 width=540 align=center>"+
                        "<tr><td colspan=2 align=center><h1>"+rb.getString("REGISTER")+"</h1></td></tr>"+
                        "<tr><td>"+rb.getString("USERNAME")+"</td><td><input type=text name=username></td></tr>"+
                        "<tr><td>"+rb.getString("PASSWORD")+"</td><td><input type=password name=password></td></tr>"+
                        "<tr><td>"+rb.getString("CONFIRM_PASS")+"</td><td><input type=password name=cPass></td></tr>"+
                        "<tr><td colspan=2 align=center><input type=submit value="+rb.getString("SUBMIT")+"></td></tr>"+
                    "</table></html>");
        res.getWriter().print(sWriter.toString());
    }//doGet

Этот код(ы) работают хорошо, когда язык en_US, но когда я меняю его на арабский или персидский, то его отображение как:

ط«ط¨طھ ظ†ط§ظ…

؛ §غŒظ…غŒظ„
±ط ظ…ط2
ظ…ط±ظˆط± ط±ظ…ط²
ط§ط±ط³ط§ظ„

Пожалуйста посоветуйте

2 ответа

  1. Лично я не вижу причин использовать listresourcebundle для строк.
    Но эй, все равно …

    Проблема здесь заключается в кодировании источника .Java-файл.

    Вы можете кодировать файл как utf-8, но компилятор Java этого не знает и использует системную кодировку.

    a. Вы можете передать необходимую кодировку компилятору с помощью-encoding:

    javac -encoding utf-8 LabelsBundle_fa_IR.java
    

    b. Вы можете Unicode-escape строк, составляющих файл ASCII.
    Символы будут нечитаемыми (будет»…\u0646…»), но для компилятора больше нет путаницы:

    native2ascii -encoding utf-8 LabelsBundle_fa_IR.java asciifile
    rename asciifile LabelsBundle_fa_IR.java
    

    Я предполагаю, что вы не посылаете .java файл для локализации 🙂
    Большинство инструментов локализации извлекают локализуемый материал из файла, переводят его и генерируют java обратно. Часто есть возможность создать его с помощью unicode-escape, поэтому нет необходимости идти до конца .java и конвертировать там.

    ===

    Это плохой ответ:

    rb.getString("USERNAME").getBytes(), "UTF-8");
    

    getBytes зависит от системной кодировки, но это кодировка времени выполнения.

    Таким образом, это кодировка вашего сервера, по сравнению с тем, который используется для компиляции файлов java для начала. Это может быть по-другому.

    ===

    Почему я предпочитаю .свойства для ListResourceBundle:

    • локализация (переводчиками, не технар )не происходит.Java-файл.
      Строки должны быть извлечены и помещены обратно. С тех пор .Java-файл
      может содержать код, а что нет, то его легче повредить в процессе.
      Большинство инструментов локализации ручка .свойства хорошо, но не ListResourceBundle

    • кодировка .свойства файла четко определены: латинский 1.
      Нет никакой «магии» и не зависит от системы.
      Таким образом, вам не нужны специальные флаги во время компиляции.

    • ListResourceBundle подходит для объектов, специфичных для локали.
      Подумайте о бизнес-логике, например, усложните налоговые правила,
      или специальные рабочие процессы. Вот почему это карта от строки к объекту.
      Вы можете, конечно, поставить струны там, но .свойства или .xml были
      разработан специально для струн.