Có rất nhiều thứ cần phải được đưa về chăm sóc trong khi quốc tế hóa ứng dụng:
phát hiện Locale
Điều đầu tiên bạn cần phải suy nghĩ về là để phát hiện Locale của người dùng cuối. Tùy thuộc vào những gì bạn muốn hỗ trợ nó có thể dễ dàng hoặc một chút phức tạp.
- Như bạn đã biết, trình duyệt web có xu hướng gửi ngôn ngữ ưa thích của người dùng cuối thông qua tiêu đề Ngôn ngữ chấp nhận HTTP. Việc truy cập thông tin này trong Servlet có thể đơn giản như gọi số
request.getLocale()
.Nếu bạn không có kế hoạch hỗ trợ bất kỳ ưa thích Locale Detection workflow, bạn có thể chỉ cần dính vào phương pháp này.
- Nếu bạn có Hồ sơ người dùng trong ứng dụng của mình, bạn có thể muốn thêm Ngôn ngữ ưa thích và Ngôn ngữ định dạng ưa thích vào nó. Trong trường hợp này, bạn cần phải chuyển miền địa phương sau khi người dùng đăng nhập.
- Bạn có thể muốn hỗ trợ chuyển đổi ngôn ngữ dựa trên URL (ví dụ: http://deutsch.example.com/ hoặc http://example.com?lang=de). Bạn sẽ cần đặt Ngôn ngữ hợp lệ dựa trên thông tin URL - điều này có thể được thực hiện theo nhiều cách khác nhau (ví dụ: Bộ lọc URL).
- Bạn có thể muốn hỗ trợ chuyển đổi ngôn ngữ (chọn ngôn ngữ từ trình đơn thả xuống hoặc thứ gì đó), tuy nhiên tôi sẽ không khuyên bạn sử dụng (trừ khi được kết hợp với điểm 3).
JSTL cách tiếp cận có thể là đủ nếu bạn chỉ muốn hỗ trợ phương pháp đầu tiên hoặc nếu bạn không có kế hoạch để thêm bất kỳ phụ thuộc bổ sung (như Spring Framework).
Trong khi chúng ta đang ở Spring Framework nó có khá một vài tính năng thú vị mà bạn có thể sử dụng cả hai để phát hiện Locale (như CookieLocaleResolver, AcceptHeaderLocaleResolver, SessionLocaleResolver và LocaleChangeInterceptor) và chuỗi externalizing và tin nhắn định dạng (xem spring:message tab).
Spring Framework sẽ cho phép bạn thực hiện khá dễ dàng tất cả các tình huống trên và đó là lý do tại sao tôi thích nó hơn.
Chuỗi externalization
Đây là cái gì đó nên được dễ dàng, phải không? Vâng, chủ yếu là - chỉ cần sử dụng thẻ thích hợp. Vấn đề duy nhất bạn có thể phải đối mặt là khi nói đến các văn bản bên ngoài (JavaScript) bên ngoài. Có một số cách tiếp cận có thể có, nhưng hãy để tôi đề cập đến hai phương pháp sau:
- Có mỗi chuỗi văn bản dịch JSP (có thẻ thông báo) và chỉ truy cập vào mảng đó trong mã máy khách. Đây là cách tiếp cận dễ dàng hơn nhưng ít bảo trì hơn - bạn sẽ cần viết các chuỗi hợp lệ từ các trang hợp lệ (các trang thực sự tham chiếu các kịch bản phía máy khách của bạn). Tôi đã làm điều đó trước đây và tin tôi, đây không phải là điều bạn muốn làm trong ứng dụng lớn (nhưng nó có lẽ là giải pháp tốt nhất cho một ứng dụng nhỏ).
- Một cách tiếp cận khác có thể có vẻ khó khăn về nguyên tắc nhưng thực tế nó dễ xử lý hơn trong tương lai. Ý tưởng là tập trung chuỗi ở phía máy khách (di chuyển chúng sang một số tệp JavaScript phổ biến). Sau đó, bạn sẽ cần phải thực hiện Servlet của riêng bạn sẽ trả về kịch bản này theo yêu cầu - nội dung cần được dịch. Bạn sẽ không thể sử dụng JSTL ở đây, bạn sẽ cần phải nhận chuỗi từ Resource Bundles trực tiếp.
Nó dễ dàng hơn nhiều để duy trì, bởi vì bạn sẽ có một, điểm trung tâm để thêm chuỗi có thể dịch.
concatenations
Tôi ghét phải nói rằng, nhưng concatenations đang thực sự đau đớn từ quan điểm Localizability. Chúng rất phổ biến và hầu hết mọi người không nhận ra nó.
Vậy thì kết nối là gì?
Về nguyên tắc, mỗi câu tiếng Anh cần được dịch sang ngôn ngữ đích.Vấn đề là, nó xảy ra nhiều lần thông điệp được dịch chính xác sử dụng thứ tự từ khác với đối tác tiếng Anh của nó (vì vậy tiếng Anh "Chính sách bảo mật" được dịch sang tiếng Ba Lan "Polityka bezpieczeństwa" - "policy" là "polityka" - thứ tự khác).
OK, nhưng cách nó liên quan đến phần mềm?
Trong ứng dụng web mà bạn có thể nối Strings như thế này:
String securityPolicy = "Security " + "policy";
hay như thế này:
<p><span style="font-weight:bold">Security</span> policy</p>
Cả hai sẽ có vấn đề. Trong trường hợp đầu tiên, bạn cần phải sử dụng phương thức MessageFormat.format()
và các chuỗi bên ngoài như (ví dụ) "Security {0}"
và "policy"
, trong trường hợp sau, bạn sẽ bên ngoài nội dung của toàn bộ đoạn (thẻ p), bao gồm thẻ khoảng. Tôi biết rằng điều này là đau đớn cho người dịch nhưng thực sự không có cách nào tốt hơn.
Đôi khi bạn phải sử dụng nội dung động trong đoạn của mình - thẻ định dạng JSTL fmt: format cũng sẽ giúp bạn ở đây (nó hoạt động vôi MessageFormat ở phía bên phụ trợ).
Layouts
Trong ứng dụng cục bộ, nó thường xảy ra rằng chuỗi dịch là cách dài hơn những tiếng Anh. Kết quả có thể trông rất xấu xí. Bằng cách nào đó, bạn sẽ cần phải sửa chữa phong cách. Có hai phương pháp tiếp cận lại:
- Khắc phục sự cố khi chúng xảy ra bằng cách điều chỉnh các kiểu phổ biến (và cầu nguyện sẽ không phá vỡ các ngôn ngữ khác). Điều này là rất đau đớn để duy trì.
- Triển khai Cơ chế địa phương hóa CSS. Cơ chế mà tôi đang nói đến sẽ phân phối tệp CSS độc lập, mặc định bằng ngôn ngữ và ghi đè theo ngôn ngữ. Ý tưởng là phải ghi đè lên tệp CSS cho từng ngôn ngữ, để bạn có thể điều chỉnh bố cục theo yêu cầu (chỉ cho một ngôn ngữ). Để làm điều đó, tệp CSS mặc định, cũng như các trang JSP không được chứa
!important
từ khóa bên cạnh bất kỳ định nghĩa kiểu nào. Nếu bạn thực sự phải sử dụng nó, hãy chuyển chúng sang en.css dựa trên ngôn ngữ - điều này sẽ cho phép các ngôn ngữ khác sửa đổi chúng.
vấn đề cụ thể Văn hóa
Tránh sử dụng đồ họa, màu sắc và âm thanh có thể được cụ thể cho văn hóa phương Tây. Nếu bạn thực sự cần nó, vui lòng cung cấp phương tiện địa phương hóa. Tránh đồ họa nhạy cảm hướng (vì đây sẽ là một vấn đề khi bạn cố gắng bản địa hóa để nói tiếng Ả Rập hoặc tiếng Do Thái). Ngoài ra, đừng cho rằng toàn thế giới đang sử dụng cùng một số (tức là không đúng đối với tiếng Ả Rập).
Ngày và múi giờ
Xử lý số ngày trong thời gian trong Java là để nói rằng ít nhất không dễ dàng. Nếu bạn không hỗ trợ bất kỳ điều gì khác ngoài Lịch Gregorian, bạn có thể gắn bó với các lớp Ngày và Lịch được xây dựng sẵn. Bạn có thể sử dụng JSTL fmt: timeZone, fmt: formatDate và fmt: parseDate để đặt đúng múi giờ, định dạng và phân tích ngày trong JSP.
tôi đề nghị sử dụng fmt: formatDate như thế này:
<fmt:formatDate value="${someController.somedate}"
timeZone="${someController.detectedTimeZone}"
dateStyle="default"
timeStyle="default" />
Điều quan trọng là ngày bí mật và thời gian là múi giờ hợp lệ (cuối của người dùng). Ngoài ra nó là khá quan trọng để chuyển đổi nó sang định dạng dễ hiểu - đó là lý do tại sao tôi đề nghị phong cách định dạng mặc định.
BTW. Phát hiện múi giờ không phải là điều dễ dàng, vì trình duyệt web không quá đẹp để gửi bất kỳ thứ gì. Thay vào đó, bạn có thể thêm lĩnh vực múi giờ ưa thích các ưu đãi tài khoản (nếu có) hoặc nhận múi giờ hiện tại bù đắp từ trình duyệt web thông qua phía client script (xem Date object's methods)
số và tiền tệ
số cũng như tiền tệ phải được chuyển đổi sang định dạng địa phương. Nó được thực hiện theo cách tương tự như định dạng ngày (phân tích cú pháp cũng được thực hiện tương tự):
<fmt:formatNumber value="1.21" type="currency"/>
điệp Compound
Bạn đã đã được cảnh báo không để nối chuỗi. Thay vào đó, bạn có thể sử dụng MessgageFormat
. Tuy nhiên, tôi phải nói rằng bạn nên giảm thiểu việc sử dụng các thông điệp ghép. Đó là vì quy tắc ngữ pháp mục tiêu khá khác nhau, vì vậy người dịch có thể không chỉ cần đặt lại câu (điều này sẽ được giải quyết bằng cách sử dụng trình giữ chỗ và MessageFormat.format()
), nhưng dịch toàn bộ câu theo cách khác nhau dựa trên những gì sẽ được thay thế . Hãy để tôi cung cấp cho bạn một số ví dụ:
// Multiple plural forms
English: 4 viruses found.
Polish: Znaleziono 4 wirusy. **OR** Znaleziono 5 wirusów.
// Conjugation
English: Program encountered incorrect character | Application encountered incorrect character.
Polish: Program napotkał nieznaną literę | Aplikacja napotkała nieznaną literę.
Mã hóa ký tự
Nếu bạn đang có kế hoạch để bản địa hoá sang ngôn ngữ mà không hỗ trợ trang mã ISO 8859-1, bạn sẽ cần phải hỗ trợ Unicode - sản phẩm tốt nhất cách là đặt mã hóa trang thành UTF-8. Tôi đã thấy những người làm việc đó như thế này:
<%@ page contentType="text/html; charset=UTF-8" %>
tôi phải cảnh báo bạn: đây là không đủ. Bạn thực sự cần phải tuyên bố này:
<%@page pageEncoding="UTF-8" %>
Ngoài ra, bạn vẫn sẽ cần phải khai báo mã trong tiêu đề trang, chỉ để được ở bên an toàn:
<META http-equiv="Content-Type" content="text/html;charset=UTF-8">
Danh sách Tôi đưa cho bạn là chưa đầy đủ nhưng đây là điểm khởi đầu tốt. Chúc may mắn :)
bản sao có thể có của [Cách quốc tế hóa ứng dụng web java.] (Http://stackoverflow.com/questions/4276061/how-to-internationalize-a-java-web-application) – BalusC