Java 웹 애플리케이션을 국제화하는 방법은 무엇입니까?


81

국제화는 웹 애플리케이션이 모든 언어를 사용하도록 만들 수있는 프로세스라는 것을 Google에서 배웠습니다. 나는에서 유니 코드에 대해 배운 그래서 나는, 국제화의 과정에 대한 유니 코드를 이해하려면 여기에있다 .

유니 코드에 대해 문자 세트가 바이트로 인코딩되고 다시 바이트가 문자 세트로 디코딩되는 방식을 이해할 수 있습니다. 그러나 나는 더 나아가는 방법을 모른다. 문자열을 비교하는 방법을 배우고 싶습니다. 웹 애플리케이션에서 국제화를 구현하는 방법을 알아야합니다. 제안 사항이 있으십니까? 나를 안내 해주세요.

내 목표 :

저의 주요 목표는 번역을위한 웹 응용 프로그램 (영어에서 아랍어로, 그 반대로)을 개발하는 것입니다. 국제화를 따르고 싶습니다. FF, Chrome, IE의 세 가지 브라우저 모두에서 번역을 위해 웹 응용 프로그램을 실행하고 싶습니다. 어떻게해야합니까?

답변:


221

기본 JSP / 서블릿 웹 애플리케이션의 경우 기본 접근 방식은 리소스 번들 과 함께 JSTL fmttaglib 를 사용하는 것 입니다. 리소스 번들에는 키가 모든 언어에 대해 동일한 상수이고 값이 언어별로 다른 키-값 쌍이 포함됩니다. 리소스 번들은 일반적으로 API에 의해로드되는 속성 파일 입니다 . 그러나 예를 들어 데이터베이스에서 키-값 쌍을로드 할 수 있도록 사용자 정의 할 수 있습니다.ResourceBundle

다음은 속성 파일 기반 리소스 번들을 사용하여 웹 애플리케이션의 로그인 양식을 국제화하는 방법의 예입니다.


  1. 다음 파일을 만들어 패키지에 넣습니다 com.example.i18n( 예 : Maven의 경우 패키지 구조 내부에 넣습니다 src/main/resources).

    text.properties (기본 언어, 일반적으로 영어로 된 키-값 쌍 포함)

     login.label.username = 사용자 이름
     login.label.password = 암호
     login.button.submit = 로그인
     

    text_nl.properties(네덜란드어 ( nl) 키-값 쌍 포함)

     login.label.username = Gebruikersnaam
     login.label.password = Wachtwoord
     login.button.submit = Inloggen
     

    text_es.properties(스페인어 ( es) 키-값 쌍 포함)

     login.label.username = 사용자 이름
     login.label.password = 콘트라 세냐
     login.button.submit = Acceder
     

    자원 번들 파일 이름은 다음 패턴을 따라야합니다 name_ll_CC.properties. _ll부분은 소문자로해야한다 ISO 693-1 언어 코드입니다. 선택 사항이며 _CC부품이 있을 때만 필요합니다 . _CC부분은 대문자이어야한다 ISO 3166-1 알파 2 국가 코드. 선택 사항이며 미국 영어 ( _en_US) 및 영국 영어 ( _en_GB) 와 같은 국가 별 언어 방언을 구별하는 데만 자주 사용됩니다 .


  2. 아직 완료되지 않은 경우 JSTL을 설치하십시오. Servlet 2.5 컨테이너 이상 (Tomcat 6.0 등)에서 실행 중이고 web.xmlServlet 2.5 사양을 준수하는 것으로 선언 된 경우 jstl-1.2.jar 을 webapp의 /WEB-INF/lib폴더 에 넣으십시오 .


  3. 다음 예제 JSP 파일을 만들어 웹 콘텐츠 폴더에 넣습니다.

    login.jsp

     <%@ page pageEncoding="UTF-8" %>
     <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
     <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
     <c:set var="language" value="${not empty param.language ? param.language : not empty language ? language : pageContext.request.locale}" scope="session" />
     <fmt:setLocale value="${language}" />
     <fmt:setBundle basename="com.example.i18n.text" />
     <!DOCTYPE html>
     <html lang="${language}">
         <head>
             <title>JSP/JSTL i18n demo</title>
         </head>
         <body>
             <form>
                 <select id="language" name="language" onchange="submit()">
                     <option value="en" ${language == 'en' ? 'selected' : ''}>English</option>
                     <option value="nl" ${language == 'nl' ? 'selected' : ''}>Nederlands</option>
                     <option value="es" ${language == 'es' ? 'selected' : ''}>Español</option>
                 </select>
             </form>
             <form method="post">
                 <label for="username"><fmt:message key="login.label.username" />:</label>
                 <input type="text" id="username" name="username">
                 <br>
                 <label for="password"><fmt:message key="login.label.password" />:</label>
                 <input type="password" id="password" name="password">
                 <br>
                 <fmt:message key="login.button.submit" var="buttonValue" />
                 <input type="submit" name="submit" value="${buttonValue}">
             </form>
         </body>
     </html>
    

    <c:set var="language">현재 언어를 관리합니다. 언어가 요청 매개 변수로 제공된 경우 (언어 드롭 다운에 의해) 설정됩니다. 그렇지 않으면 해당 언어가 세션에서 이미 설정되어있는 경우 대신 그대로 사용하십시오. 그렇지 않으면 요청 헤더에서 사용자 제공 로케일을 사용하십시오.

    <fmt:setLocale>자원 번들의 로케일을 설정합니다. 그것은이 줄은 것이 중요 하기 전에<fmt:setBundle> .

    (가) <fmt:setBundle>의 기본 이름으로 자원 번들을 초기화 (즉,없는 유일한 이름까지 전체 수식 패키지 이름 _ll_CC지정).

    <fmt:message>를 검색 지정된 번들 키로 메시지 값입니다.

    <html lang="${language}">알리는 페이지가 표시되지 않도록에서 어떤 언어 searchbots (SEO에 따라서, 좋은) 중복 콘텐츠로.

    다른 언어를 선택하면 언어 드롭 다운이 JavaScript에 의해 즉시 제출되고 페이지가 새로 선택한 언어로 새로 고쳐집니다.


그러나 속성 파일은 기본적으로 ISO-8859-1 문자 인코딩을 사용하여 읽습니다. 유니 코드 이스케이프로 이스케이프해야합니다. 이것은 JDK 제공 native2ascii.exe도구를 사용하여 수행 할 수 있습니다 . 자세한 내용은 이 기사 섹션 을 참조하십시오 .

이론적 인 대안은 Control해당 파일을 UTF-8로로드 하는 사용자 정의 가 포함 된 번들을 제공하는 것이지만 안타깝게도 기본 JSTL fmttaglib 에서 지원하지 않습니다 . .NET Framework의 도움으로 모든 것을 직접 관리해야합니다 Filter. JSF와 같이보다 투명한 방식으로이를 처리 할 수있는 (MVC) 프레임 워크가 있습니다 . 이 기사를 참조하십시오 .


2
이 멋진 솔루션에는 한 가지 문제가 있습니다. "en_US"에서와 같이 요청에서 가져온 로케일은 잘못된 HTML 인 <html lang = "en_US">를 제공하는 언어 및 국가 일 수 있습니다. lang 속성의 값으로 로케일의 언어 부분 "en"만 사용해야합니다.
Torsten Römer 2013

1
위에서 설명한 국제화 방법은 표시된 언어에 따라 URL을 수정하지 않습니다. 언어에 따라 URL을 업데이트하는 방법에 대한 제안이 있습니까? 색인 생성을 위해 다른 언어에 별도의 URL을 사용하는 것이 좋습니다. support.google.com/webmasters/answer/…
theyuv

1
언어 리소스 (test.properties 및 text_en.properties 파일) 파일을 application / resources 루트에 넣으면 다음과 같이 fmt : bundle을 설정할 수 있습니다. <fmt : setBundle basename = "text"/>
Bahadir Tasdemir

1
@bahadirT : "test"가 오타라고 가정하면 맞습니다. 는 basename파일 확장자없이 기본 이름을 나타내야합니다. 패키지로 구성하지 않는 것은 좋지 않은 습관입니다.
BalusC

1
@theyuv : User has {0} review{0,choice,0#s|1#|1<s} docs.oracle.com/javase/8/docs/api/java/text/MessageFormat.html
BalusC

26

BalusC가 말한 것 외에도 방향성에주의해야합니다 (영어는 왼쪽에서 오른쪽으로, 아랍어는 반대 방향으로 작성되기 때문입니다). 가장 쉬운 방법은 dir속성을 htmlJSP 웹 페이지의 요소에 추가 하고 외부화하는 것이므로 값은 다른 요소 또는 속성과 마찬가지로 속성 파일에서 가져옵니다.

<html dir="${direction}">
...
</html>

또한 이러한 응용 프로그램을 스타일링하는 데 문제가 거의 없습니다. 절대 위치 지정은 피해야합니다. 어떤 이유로 든 그것을 피할 수 없다면, (각각?) 언어마다 다른 스타일 시트를 사용하거나 verboten , 즉 레이아웃 관리를위한 테이블을 사용할 수 있습니다. div 요소를 사용하려는 경우 "대칭"왼쪽 및 오른쪽 스타일 속성 (둘 다 동일한 값을 가짐)과 함께 상대적 위치 지정을 사용하는 것이 좋습니다. 이것이 방향 전환이 작동하도록 만드는 이유입니다.

양방향 웹 사이트에 대한 자세한 내용은 여기에서 찾을 수 있습니다 .


7
예, 실제로 그것도 고려해야합니다.
BalusC 2010

4
<html dir="RTL">또는 <html dir="LTR">. 기본값은<html dir="LTR">
Fahim Parkar

2

이 튜토리얼을 기반으로 GAE-Google의 App Engine에서 다음을 사용하고 있습니다.

다음과 같은 jsp 파일 :

<%@ page import="java.io.* %>
<% 
  String lang = "fr"; //Assign the correct language either by page or user-selected or browser language etc.
  ResourceBundle RB = ResourceBundle.getBundle("app", new Locale(lang));
%>                 

<!DOCTYPE html>
<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<head>
</head>
<body>
  <p>      
    <%= RB.getString("greeting") %>
  </p>
</body>

그리고 다음과 같은 파일을 추가합니다 : app.properties(기본값) 및 app_fr.properties(모든 언어에 대해 등등). 이러한 각 파일에는 다음과 같이 필요한 문자열이 포함되어야합니다. key : value_in_language, 예 : app_fr.properties포함 :

greeting=Bonjour!

app.properties 포함 :

greeting=Hello!

그게 다야


10
으으, Scriptlets!
Nestor Hernandez Loli
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.