Tuỳ biến ResourceBundle.Control trong Java để đọc văn bản UTF-8 Encoding
Java
68
White

Dang Viet Ha viết ngày 20/03/2016

Hầu hết từ trước đến nay các dự án phát triển bằng ngôn ngữ Java hỗ trợ đa ngôn ngữ từ bundle resource file *.properties thì đều sử dụng tool có sẵn trong JDK, native2acsii, để convert văn bản từ native text sang hexa unicode. Việc này gây khó khăn khi người dùng cuối muốn thay đổi nội dung văn bản thì phải nhờ đội phát triển hoặc phải làm thêm thao tác chạy lệnh để convert file properties khá là phức tạp và lại phải cài đặt cả JDK. Vậy có cách nào có thể load file properties đa ngôn ngữ mà không cần convert như trên không. Câu trả lời là có.

  1. Cách thứ nhất là sử dụng file xml để lưu resource bundle thì đã hỗ trợ sẵn UTF-8 mà chúng ta không cần phải làm thêm thao tác gì. Điều này có thể thấy rõ trong lập trình Android cho di động.

  2. Vì một lý do nào đó mà chúng ta muốn load file *.properties dưới định dạng UTF-8 thì làm thế nào? Cũng không quá phức tạp. Java API đã cung cấp sẵn một method sau đây để load file resource bundle.

    getBundle(String baseName, Locale targetLocale, ResourceBundle.Control control)
    

Điều tuyệt diệu nằm ở control parameter. Nếu đọc vào code của Java bạn có thể dễ dàng thấy khi load file properties thì Java không hề chỉ định là sử dụng encoding nào nên encoding mặc định được Java sử dụng sẽ là ISO-8059-1; điều này dẫn đến việc làm vỡ toàn bộ những font không thuộc encoding ISO-8059-1. Như vậy những văn bản tiếng Việt, tiếng Nhật hay tiếng Pháp đều không hiển thị đúng như chúng ta mong muốn.

Bên dưới là source code nguyên bản của class control, bạn hãy chú ý đến dòng code BufferedInputStream bis = new BufferedInputStream(stream); Java không hề chỉ định encoding nào.

    ResourceBundle rb = ResourceBundle.getBundle("Messages",
     new ResourceBundle.Control() {
         public List getFormats(String baseName) {
             if (baseName == null)
                 throw new NullPointerException();
             return Arrays.asList("xml");
         }
         public ResourceBundle newBundle(String baseName,
                                         Locale locale,
                                         String format,
                                         ClassLoader loader,
                                         boolean reload)
                          throws IllegalAccessException,
                                 InstantiationException,
                                 IOException {
             if (baseName == null || locale == null
                   || format == null || loader == null)
                 throw new NullPointerException();
             ResourceBundle bundle = null;
             if (format.equals("xml")) {
                 String bundleName = toBundleName(baseName, locale);
                 String resourceName = toResourceName(bundleName, format);
                 InputStream stream = null;
                 if (reload) {
                     URL url = loader.getResource(resourceName);
                     if (url != null) {
                         URLConnection connection = url.openConnection();
                         if (connection != null) {
                             // Disable caches to get fresh data for
                             // reloading.
                             connection.setUseCaches(false);
                             stream = connection.getInputStream();
                         }
                     }
                 } else {
                     stream = loader.getResourceAsStream(resourceName);
                 }
                 if (stream != null) {
                     BufferedInputStream bis = new BufferedInputStream(stream);
                     bundle = new XMLResourceBundle(bis);
                     bis.close();
                 }
             }
             return bundle;

Để chỉ định Java load file theo một encoding cụ thể rất dễ dàng bằng cách viết một control class mới extends từ control class của Java, sau đó overwrite method newBundle() để chỉ định encoding. Ví dụ chúng ta thêm một UTF8Control class để load file properties theo định dạng UTF-8, thì chúng ta sẽ làm như sau. Toàn bộ source code của giữ nguyên như class control, công việc của chúng ra chỉ đơn giản là copy & paste). Sau đó, thay đổi dòng code BufferedInputStream bis = new BufferedInputStream(stream); thành BufferedInputStream bis = new BufferedInputStream(new InputStream(stream,"UTF-8")); để chỉ định encoding là xong.

Cuối cùng, khi load file resource bundle thông qua method newBundle() ở trên chúng ta chỉ cần sử dụng UTF8Control là được kết quả như mong muốn.

ResourceBundle bundle = ResourceBundle.newBundle("XYZbundle", new Local("vi-vn"), new UTF8Control());
Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Dang Viet Ha

12 bài viết.
22 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
14 0
Trong thời điểm hiện tại thì JSON REST API vẫn đang rất phổ biến và phổ thông nhất bởi tính dễ sử dụng của nó. Tuy nhiên, các hãng công nghệ lớn lu...
Dang Viet Ha viết hơn 1 năm trước
14 0
White
11 2
Gần đây, tôi có tham gia vào một sự kiện của (Link) và biết được việc sử dụng (Link) để tự động hoá công việc của các sysadmin khá tiện dụng. Hôm n...
Dang Viet Ha viết gần 2 năm trước
11 2
White
8 4
Dang Viet Ha viết gần 2 năm trước
8 4
Bài viết liên quan
White
0 0
Trong bài viết này, một số hình ảnh hoặc nọi dung có thể bị thiếu do quá trình chế bản. Vui lòng xem nội dung ở blog gốc sau: (Link) (Link), chúng...
programmerit viết hơn 2 năm trước
0 0
Male avatar
8 5
Facade Design Patern Facade Patern thuộc vào họ mô hình cấu trúc (structural patern). Facade patern phát biểu rằng : "just provide a unified an...
DuongVanTien viết hơn 1 năm trước
8 5
White
0 2
(Link), mình đã nêu ra các phần mềm chính (portal, sdk và ide). Trong phần này, mình sẽ hướng dẫn cụ thể cài đặt môi trường máy chủ và môi trường l...
programmerit viết hơn 2 năm trước
0 2
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
12 bài viết.
22 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!