다국어 처리는 웹 브라우저를 사용하는 국가에 따라 다양한 언어 및 지역을 지원하는 서비스를 말한다. 즉 다른 언어와 지역적 차이를 기술 변경 없이 소프트웨어에 바로 적용하는 것이다. 예전에는 국제적잉ㄴ 환경에서 서비스될 웹 사이트를 구축할 때 국가별로 페이지를 만들어야 했다. 이렇게 국가별 언어로 변형하여 웹 사이트를 제작하고 유지 관리하는 일은 시간이 오래 걸리고 어렵다.
하지만 JSP페이지에 JSTL의 fmt 태그를 아ㅣ용하면 언어별로 페이지를 따로 만들 필요 없이 아주 간단하게 다국어를 지원할 수 있다. 다국어는 다양한 언어와 지역에 적용될 수 있도록 하는 국제화와 언어별 구성 요소를 추가하여 특징 지역의 언어나 문화에 맞추는 지역화를 포함한다.
지역화는 사용 국가별 환경에서 특정 언어와 지역에 맞게 적합화하는 것으로, 줄여서 L10n으로 표기하기도 한다.
국제화는 여러 국가에서 사용할 수 있도록 다국어를 지원하는 것으로, 줄여서 il18n으로 표기하기도 한다. 국제화는 어느 국가에서나 사용할 수 있게 하는 지역화 기능을 포함한다.
Locale 클래스는 특정 지리적, 정치적, 문화적 지역을 나타내는 클래스로, 사용자의 지역 환경에 따라 결정되는 지역적 문화(언어, 날짜, 시간 등)의 정보를 담고 있다. 예를 들어 웹 페이지에 보이는 메시지가 여러 가지 언어로 주어졌을 때 사용자가 어떤 언어로 출력할 것인지 결정할 수 있게 하는 수단이 바로 Locale 클래스이다. Locale 클래스는 단순한 메시지뿐 아니라 숫자, 날짜, 시간 등을 표현하는 데 사용된다.
Locale 객체의 생성은 request 내장 객체를 이용하여 현재 웹 브라우저에 미리 정의된 언어나 국가 정보를 가져오는 방법이다. Locale 클래스를 사용하려면 JSP 페이지에 page 디렉티브 태그의 import 속성으로 패키지 java.util.Locale을 설정해야 한다.
java.util.Locale request.getLocale();
Locale 클래스를 생성하는 또 다른 방법
- 인스턴스화 방법
Locale locale = new Locale("ko", "KR");
- 미리 정의된 필드 값을 사용하는 방법
Locale locale = Locale.KOREA;
사용자가 웹 브라우저를 사용할 때는 웹 브라우저에 설정된 국가와 언어 이름을 통해 해당 국가의 언어로 볼 수 있다. 이처럼 웹 브라우저에 설정된 국가와 언어 이름을 알아내는 것을 로케일 감지라고 한다.
| 메소드 | 반환 유형 | 설명 |
|---|---|---|
| getDefault() | static Locale | 디폴트 로케일의 현재 값을 가져온다. |
| getCountry() | String | 현재 로케일의 국가/지역 코드(대문자)를 가져온다. |
| getDisplayCountry() | String | 현재 로케일의 국가 이름을 가져온다. |
| getLanguage() | String | 현재 로케일의 언어 코드(소문자)를 가져온다. |
| getDisplayLanguage() | String | 현재 로케일의 언어 이름을 얻어온다. |
<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import="java.util.Locale"%>
<%
Locale locale = request.getLocale();
String displayLanguage = locale.getDisplayLanguage();
String language = locale.getLanguage();
String displayCountry = locale.getDisplayCountry();
String country = locale.getCountry();
%>
<html>
<head>
<title>Localization</title>
</head>
<body>
<%
out.println("로케일 언어 : " + displayLanguage + "<br />");
out.println("로케일 언어 코드 : " + language + "<br />");
out.println("로케일 국가 : " + displayCountry + "<br />");
out.println("로케일 국가 코드 : " + country + "<br />");
%>
</body>
</html>
다양한 국가별 언어를 제대로 표현하기 위해 response 내장 객체의 setHeader() 메소드를 사용한다. 이 메소드에 Content-Language 헤더 값을 언어 코드로 설정하고 HTML 엔티티 코드나 이름을 사용하면 모든 특수문자를 출력할 수 있다.
response 내장 객체의 setHeader() 메소드를 이용하여 Content-Language 헤더 값에 스페인어 코드 es를 설정한다. 그리고 스페인어의 특수문자를 출력하기 위해 HTML 엔티티 이름을 사용한다.
사용자의 로케일에 따라 특정 날짜와 시간 형식을 표현하기 위해 DateFormat 클래스의 getDateTimeinstance() 메소드를 사용한다. DateFormat 클래스를 사용하려면 JSP 페이지에 page 디렉티브 태그의 import 속성으로 패키지 java.text.DateFormat을 설정해야 한다.
사용자의 로케일에 따라 특정 통화와 숫자를 표현하기 위해 NumberFormat 클래스의 getCurrencyInstance() 메소드를 사용한다. 또한 특정 비율을 표현하는 데에는 getPercent Instance()메소드를 사용한다. NumberFormat 클래스를 사용하려면 JSP 페이지에 page 디렉티브 태그의 import 속성으로 패키지 java.text.NumberFormat을 설정해야 한다.
<%@page import="java.text.NumberFormat"%>
<%@page import="java.text.DateFormat"%>
<%@page import="java.util.Date"%>
<%@page import="java.util.Locale"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h3>현재 로케일의 국가, 날짜, 통화</h3>
<%
Locale locale = request.getLocale();
Date currentDate = new Date();
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, locale);
NumberFormat numberFormat = NumberFormat.getNumberInstance(locale);
%>
<p> 국가 : <%=locale.getDisplayCountry() %>
<p> 날짜 : <%=dateFormat.format(currentDate) %>
<p> 숫자 (12345.67) : <%=numberFormat.format(12345.67) %>
</body>
</html>
JSTL fmt 태그는 다국어 문서 처리를 위한 국제화 및 지역화 태그이다. 날짜와 숫자 등을 형식화하는 기능을 제공하는 JSTL 라이브러리인 JSTL fmt 태그는 특정 지역에 따라 다른 메시지를 출력할 때 사용한다. 예를 들면 한글 웹 브라우저는 한글 메시지를 출력할 때, 영문 웹 브라우저는 영어 메시지를 출력할 때 유용하다.
이와 같이 JSTL fmt 태그는 중복 작업을 없애고 하나의 JSP 페이지에서 다양한 언어에 맞는 메시지를 출력하게 한다. JSTL fmt 태그 라이브러리를 사용하려면 다음과 같이 JSP 페이지에 taglib 디렉티브 태그로 서식 라이브러리를 포함해야 한다. 또한 JSTL 라이브러리인 jstl.jar파일이 필요하다.
<% taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
여기서 uri 속성은 사용자가 정의한 태그의 설정 정보가 담긴 경로 주소이다. prefix 속성은 uri에 설정한 주소를 사용자가 정의한 태그로 식별하는 데 쓰이는 고유 이름이다. uri 속성 값을 그대로 사용하면 복잡하므로 prefix 속성 값이 대신 식별할 수 있게 해준다.
| 구분 | 태그 유형 | 설명 |
|---|---|---|
| Locale 설정 | setLocale | 로케일을 설정한다. |
| " | requestEncoding | 요청 파라미터의 문자 인코딩을 설정한다. |
| 메시지 처리 | bundle | 사용할 리소스번들을 설정한다. |
| " | message | 리소스번들에서 로케일에 맞는 메시지를 가져와 출력한다. |
| " | setBundle | 리소스번들을 읽어와 특정 변수에 저장한다. |
| 날짜 | formatDate | 날짜 형식을 표현한다. |
| " | parseDate | 문자열에서 원하는 패턴의 날짜 형식으로 변환한다. |
| 숫자 | parseNumber | 문자열에서 원하는 패턴의 숫자 형식으로 변환한다. |
| " | formatNumber | 숫자 형식을 표현한다. |
| 시간 | setTimeZone | 특정 범위의 시간대를 설정한다. |
| " | timeZone | 시간대를 설정한다. |
setLocale 태그는 국제화 태그가 사용할 로케일을 설정하는 태그이다. setLocale 태그는 다국어를 지원하는 웹 페이지를 만들 때 리소스번들(ResourceBundle)인 *.properties 파일과 연계하여 사용한다.
<fmt:setLocale value="언어 코드[_국가 코드]" [scope="{page|request|session|application}"]/> //기본 값은 page
value 속성 값에서 언어 코드는 두 글자로 된 소문자로서 필수이고, 국가 코드는 두 글자로 된 대문자로서 추가로 설정한다. 언어 코드와 국가 코드를 모두 설정하려면 붙임표(-)나 밑줄(_)로 구분해야 한다. scope 속성 값으로 page,request,session,application 중 하나를 설정하거나 생략할 수 있는데, 생략하면 기본 값인 page로 설정된다.
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%=response.getLocale()%>
<fmt:setLocale value="ko"/>
<p><%=response.getLocale()%>
<fmt:setLocale value="ja"/>
<p><%=response.getLocale()%>
<fmt:setLocale value="en"/>
<p><%=response.getLocale()%>
</body>
</html>
requestEncoding 태그는 요청 파라미터의 문자 인코딩을 설정하는 태그이다. 이 태그는 request 내장 객체의 setCharacterEncoding() 메소드와 동일한 역할을 한다.
<fmt:requestEncoding value="문자 인코딩" />
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<fmt-requestEncoding value="enc-kr"/>
요청 파라미터 :
<%
out.print(request.getParameter("id"));
%>
<form method="post" action="#">
<p> 아이디<input type="text" name="id">
<input type="submit" value="전송">
</form>
</body>
</html>
리소스번들은 메시지 처리 태그에서 사용하는 파일로 메시지번들이라고도 한다. 리소스번들로 사용하는 파일은 보통 WEB-INF/classes/ 폴더에 있다. 리소스번들은 java.util.Properties 클래스에 정의 된 방법으로 메시지를 읽어오기 때문에 확장자가 properties인 파일이 반드시 있어야 한다. java.util.Properties 클래스는 알파벳이나 숫자, 라틴 문자 외의 언어를 유니코드 값으로 표현한다.
| *.properties 파일 | 설명 |
|---|---|
| 파일 이름.properties | 기본 메시지일 때 사용한다. |
| 파일 이름_ko.properties | 한글 메시지일 때 사용한다. |
| 파일 이름_en.properties | 영어 메시지일 때 사용한다. |
//message_ko.properties 파일인 경우
NAME = 홍길동
//mssage_en.properties 파일인 경우
NAME = your name
bundle 태그는 사용할 리소스번들을 설정하는 태그이다. 이 태그는 리소스번들로 사용할 *.properties 파일을 읽어오는 역할을 하며 message 태그와 함께 사용한다.
message 태그는 bundle 태그에 설정한 리소스번들에서 메시지를 읽어와 출력하는 태그이다.
//message_en.properties 파일인 경우
name = admin
hello = How are You
//message.properties 파일인 경우
name = \uAD00\uB9AC\uC790 //"관리자" 유니코드
hello = \uC548\uB155\uD558\uC694 // "안녕하세요" 유니코드
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<fmt:bundle basename="resourceBundle.message">
<p><fmt:message key="name"/>
<fmt:message key="hello" var="msg" />
<p>${msg}
</fmt:bundle>
</body>
</html>
setBundle 태그는 리소스번들을 가져와 변수로 저장한 후 JSP 페이지 어디에서나 사용할 수 있는 태그이다. 이 태그는 bundle 태그를 대체하여 사용할 수 있다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<fmt:setBundle var="message" basename="resourceBundle.message"/>
<p><fmt:message bundle="${message}" key="name"/>
<fmt:message bundle="${message}" key="hello" var="msg" />
<p>${msg}
</body>
</html>
formatNumber 태그는 숫자를 형식에 맞춰 출력하는 태그이다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<p>숫자 : <fmt:formatNumber value="1234.567" type="number" />
<p>통화 : <fmt:formatNumber value="1234.567" type="currency" currencySymbol="원"/>
<p>퍼센트 : <fmt:formatNumber value="1234.567" type="percent" />
<p>패턴(.0000) : <fmt:formatNumber value="1234.567" pattern=".0000" />
</body>
</html>
parseNumber 태그는 formatNumber 태그와 반대로 사용자가 설정한 패턴 문자열에서 숫자를 추출하는 태그이다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<p>패턴(없음) : <fmt:parseNumber value="1234.567" />
<p>패턴(0000.000) : <fmt:parseNumber value="1234.567" pattern="0000.000" />
<p>패턴(####.###) : <fmt:parseNumber value="1234.567" pattern="####.### />
</body>
</html>
formatDate 태그는 날짜 정보를 담고 있는 객체를 형식화하여 출력하는 태그이다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<jsp:useBean id="now" class="java.util.Date" />
<p> date 형식 : <fmt:formatDate value="${now}" type="data" />
<p> time 형식 : <fmt:formatDate value="${now}" type="time" />
<p> both 형식 : <fmt:formatDate value="${now}" type="both" />
</body>
</html>
parseDate 태그는 문자열로 표시된 날짜와 시간 값을 java.util.Date로 변환하는 태그이다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<p><fmt:parseDate value="20220428230605" pattern="yyyyMMddmmss" />
<p><fmt:parseDate pattern="yyyyMMddHHmmss"> 20220428230605</fmt:parseDate>
<p><fmt:parseDate value="20220428230605" pattern="yyyyMMddHHmmss" var="date" scope="page"/>
<p><fmt:formatDate calue="${date}" pattern="yyyy-HH-dd HH:mm" />
</body>
</html>
timeZone 태그는 시간대별로 시간을 처리하는 태그이다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<jsp:useBean id="now" class="java.util.Date" />
<p> 한국 : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
<p><fmt:timeZone value="GMT-8">
뉴욕 : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
</fmt:timeZone>
<p><fmt:timeZone value="GMT">
런던 : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
</fmt:timeZone>
</body>
</html>
setTimeZone 태그는 특정 영역 범위의 시간대별로 시간을 처리하는 태그이다.
<%@ page contantType="text/html; charset=utf-8" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Internationalization</title>
</head>
<body>
<jsp:useBean id="now" class="java.util.Date" />
<p> 한국 : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
<p><fmt:setTimeZone value="GMT-8">
뉴욕 : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
</fmt:timeZone>
<p><fmt:setTimeZone value="GMT">
런던 : <fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
</fmt:timeZone>
</body>
</html>