JSP 다국어 처리

박승현·2022년 5월 2일

JSP

목록 보기
8/11

다국어 처리의 개요

다국어 처리는 웹 브라우저를 사용하는 국가에 따라 다양한 언어 및 지역을 지원하는 서비스를 말한다. 즉 다른 언어와 지역적 차이를 기술 변경 없이 소프트웨어에 바로 적용하는 것이다. 예전에는 국제적잉ㄴ 환경에서 서비스될 웹 사이트를 구축할 때 국가별로 페이지를 만들어야 했다. 이렇게 국가별 언어로 변형하여 웹 사이트를 제작하고 유지 관리하는 일은 시간이 오래 걸리고 어렵다.

하지만 JSP페이지에 JSTL의 fmt 태그를 아ㅣ용하면 언어별로 페이지를 따로 만들 필요 없이 아주 간단하게 다국어를 지원할 수 있다. 다국어는 다양한 언어와 지역에 적용될 수 있도록 하는 국제화와 언어별 구성 요소를 추가하여 특징 지역의 언어나 문화에 맞추는 지역화를 포함한다.

지역화

지역화는 사용 국가별 환경에서 특정 언어와 지역에 맞게 적합화하는 것으로, 줄여서 L10n으로 표기하기도 한다.

  • 숫자, 날짜, 시간의 형식
  • 화폐의 표시
  • 키보드의 지원
  • 문자열의 순서와 정렬
  • 심벌, 아이콘, 색상
  • 문화에 따라 오해의 소지가 있거나 의미가 없는 문자, 그림
  • 지역별 법률의 차이

국제화

국제화는 여러 국가에서 사용할 수 있도록 다국어를 지원하는 것으로, 줄여서 il18n으로 표기하기도 한다. 국제화는 어느 국가에서나 사용할 수 있게 하는 지역화 기능을 포함한다.

  • 국제화 지원은 유니코드의 사용이나 기존의 인코딩을 적절히 처리하고 사용자 인터페이스에 표시할 문자열에는 문자 코드가 포함되지 않도록 설계 및 개발해야 한다.
  • 국제화를 처리하는 정보에 언어 정보를 포함하거나, 세로쓰기/가로쓰기/우측에서 좌측으로의 가로쓰기 등 언어의 특성을 반영하는 처리 등을 지원해야 한다.
  • 날짜와 시간 표시, 지역의 달력, 숫자 표시, 리스트의 정렬과 표시, 인명이나 주소의 처리 등 언어의 특성(언어적, 지역적, 문화적 특성 등)에 대한 사용자 설정을 지원해야 한다.
  • 국제화는 사용자의 요청이나 설정에 따라 필요시 사용되도록 지역화 정보를 코드와 분리해야 한다.

Locale 클래스를 이용한 다국어 처리

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 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 속성 값이 대신 식별할 수 있게 해준다.

[JSTL fmt 태그의 종류]

구분태그 유형설명
Locale 설정setLocale로케일을 설정한다.
"requestEncoding요청 파라미터의 문자 인코딩을 설정한다.
메시지 처리bundle사용할 리소스번들을 설정한다.
"message리소스번들에서 로케일에 맞는 메시지를 가져와 출력한다.
"setBundle리소스번들을 읽어와 특정 변수에 저장한다.
날짜formatDate날짜 형식을 표현한다.
"parseDate문자열에서 원하는 패턴의 날짜 형식으로 변환한다.
숫자parseNumber문자열에서 원하는 패턴의 숫자 형식으로 변환한다.
"formatNumber숫자 형식을 표현한다.
시간setTimeZone특정 범위의 시간대를 설정한다.
"timeZone시간대를 설정한다.

로케일 설정 태그의 기능과 사용법

setLocale 태그

setLocale 태그는 국제화 태그가 사용할 로케일을 설정하는 태그이다. setLocale 태그는 다국어를 지원하는 웹 페이지를 만들 때 리소스번들(ResourceBundle)인 *.properties 파일과 연계하여 사용한다.

<fmt:setLocale value="언어 코드[_국가 코드]" [scope="{page|request|session|application}"]/> //기본 값은 page

value 속성 값에서 언어 코드는 두 글자로 된 소문자로서 필수이고, 국가 코드는 두 글자로 된 대문자로서 추가로 설정한다. 언어 코드와 국가 코드를 모두 설정하려면 붙임표(-)나 밑줄(_)로 구분해야 한다. scope 속성 값으로 page,request,session,application 중 하나를 설정하거나 생략할 수 있는데, 생략하면 기본 값인 page로 설정된다.

[setLocale 태그 사용 예]

<%@ 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 태그]

requestEncoding 태그는 요청 파라미터의 문자 인코딩을 설정하는 태그이다. 이 태그는 request 내장 객체의 setCharacterEncoding() 메소드와 동일한 역할을 한다.

<fmt:requestEncoding value="문자 인코딩" />

[requestEncoding 태그 사용 예]

<%@ 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 태그

bundle 태그는 사용할 리소스번들을 설정하는 태그이다. 이 태그는 리소스번들로 사용할 *.properties 파일을 읽어오는 역할을 하며 message 태그와 함께 사용한다.

message 태그

message 태그는 bundle 태그에 설정한 리소스번들에서 메시지를 읽어와 출력하는 태그이다.

[bundle 태그와 message 태그 사용 예]

//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 태그

setBundle 태그는 리소스번들을 가져와 변수로 저장한 후 JSP 페이지 어디에서나 사용할 수 있는 태그이다. 이 태그는 bundle 태그를 대체하여 사용할 수 있다.

[setBundle 태그와 message 태그 사용 예]

<%@ 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 태그

formatNumber 태그는 숫자를 형식에 맞춰 출력하는 태그이다.

[formaatNumber 태그 사용 예]

<%@ 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태그

parseNumber 태그는 formatNumber 태그와 반대로 사용자가 설정한 패턴 문자열에서 숫자를 추출하는 태그이다.

[parseNumber 태그 사용 예]

<%@ 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 태그

formatDate 태그는 날짜 정보를 담고 있는 객체를 형식화하여 출력하는 태그이다.

[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

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 태그

timeZone 태그는 시간대별로 시간을 처리하는 태그이다.

[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 태그

setTimeZone 태그는 특정 영역 범위의 시간대별로 시간을 처리하는 태그이다.

[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>
profile
그냥 해보자 안되더라도 해보자 끝까지 해보자

0개의 댓글