Bộ sưu tập

i18n trong Spring MVC


https://codersontrang.com/2013/04/09/i18n-trong-spring-mvc/

Đối với một trang web có đối tượng người sử dụng ở các vùng miền khác nhau thì việc quốc tế hóa là vô cùng quan trọng. Việc quốc tế hóa có nghĩa là làm cho ứng dụng có khả năng hiển thị nội dung dưới nhiều ngôn ngữ khác nhau. Quốc tế hóa trong tiếng Anh gọi là Internationalization, vì có 18 chữ cái ở giữa chữ cái i và chữ cái n nên hay được gọi ngắn gọn là i18n. Bài viết này sẽ hướng dẫn cách thức để áp dụng i18n trong Spring MVC. Chúng ta sẽ dùng chính ví dụ trong bài viết giới thiệu về Spring MVC để minh họa.

Spring MVC đã hỗ trợ các lớp có sẵn để chúng ta có thể dễ dàng sử dụng bằng cách cấu hình trong file .xml. Để triển khai i18n vào ví dụ, ta thêm thông tin cấu hình vào file springmvcdemo-servlet.xml như sau:

springmvcdemo-servlet.xml

 <?xml version="1.0" encoding="UTF-8"?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
      xmlns:context="http://www.springframework.org/schema/context"  
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
      xmlns:mvc="http://www.springframework.org/schema/mvc"  
      xsi:schemaLocation="  
           http://www.springframework.org/schema/mvc  
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
     http://www.springframework.org/schema/beans     
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
     http://www.springframework.org/schema/context   
     http://www.springframework.org/schema/context/spring-context-3.0.xsd">  

      <context:component-scan base-package="springmvcdemo.controller" />  

       <bean id="messageSource"  
             class="org.springframework.context.support.ReloadableResourceBundleMessageSource">  
        <property name="basename" value="classpath:messages" />  
        <property name="defaultEncoding" value="UTF-8"/>  
      </bean>
  
      <bean id="localeChangeInterceptor"  
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">  
        <property name="paramName" value="lang" />  
      </bean>  

      <bean id="localeResolver"  
        class="org.springframework.web.servlet.i18n.SessionLocaleResolver">  
        <property name="defaultLocale" value="en"/>  
      </bean>  

      <mvc:interceptors>  
           <bean parent="localeChangeInterceptor"/>  
      </mvc:interceptors>  
 </beans>  

Ta thêm vào file cấu hình để khởi tạo một đối tượng của lớp ReloadableResourceBundleMessageSource. Trong đối tượng này ta chỉ ra giá trị của thuộc tính baseName là tên của file tài nguyên mà ở đó ta lấy ra các đoạn văn bản ở các ngôn ngữ khác nhau.

Các file tài nguyên là các file .properties. Trong tên của các file này sẽ bao gồm tên gốc mà chúng ta chỉ ra ở trên. Ngoài ra tiếp nối theo sau sẽ là mã của một ngôn ngữ nhất định. Như chúng ta có thể thấy, trong ví dụ chỉ ra tên cơ bản là messages, và ta áp dụng hai ngôn ngữ là tiếng Việt và tiếng Anh, vì vậy ta cũng có hai file tài nguyên tương ứng là messages_vi.propertiesmessages.properties. “classpath:” chỉ ra rằng vị trí của các file tài nguyên là nằm trong class path.

Tiếp theo trong thông tin cấu hình ta khởi tạo một bean có tên là localeChangeInterceptor và chỉ ra giá trị của thuộc tính paramName của nó. Interceptor được cài đặt để chạy ngay khi bắt đầu một phương thức trong controller bằng cách khai báo nó trong the <mvc:interceptor>. Giá trị của thuộc tính paramName chính là tên của biến sẽ được sử dụng để lưu ngôn ngữ đang được sử dụng. Ở ví dụ này, biến lang chính là biến mà interceptor sẽ sử dụng để biết được ngôn ngữ hiện tại là ngôn ngữ gì để load thông tin từ file tài nguyên tương ứng với ngôn ngữ đó.

Một bean của lớp SessionLocaleResolver được tạo ra để lưu giá trị của ngôn ngữ hiện tại vào session. Nếu như không tìm được thông tin trong session thì sẽ báo interceptor để load thông tin từ file tài nguyên của ngôn ngữ mặc định. Giá trị mặc định được chỉ ra bằng cách đặt giá trị cho thuộc tính defaultLocale của resolver. Trodng ví dụ của chúng ta, giá trị này là en ,có nghĩa ngôn ngữ hiển thị mặc định là tiếng Anh

Quay trở lại với các file tài nguyên, như đã nói ở trên ta có hai file tài nguyên tương ứng với hai ngôn ngữ là tiếng Việt và tiếng Anh. Từ Elipse IDE ta tạo một source folder bằng cách chọn File –> New –> Other như sau

i18n_1

Đặt tên cho source folder là resources và sau đó tạo ra 2 file tài nguyên có tên là messages.propertiesmessages_vi.properties sao cho cấu trúc của Project giống như hình dưới đây:

i18n_2

Nội dung của hai file tài nguyên sẽ như sau:

messages.properties

 
 header.title = Example :: Spring Application  
 
 body.title1 = CoderSonTrang - Spring MVC Demo  
 body.title2 = Student Book Show   
 
 body.form.your_name = Your name  
 body.form.your_list_of_book = Edit your list of books  
 body.form.button.submit = Submit  

messages_vi.properties

 
 header.title = Ví dụ :: Ứng dụng sử dụng Spring  
 
 body.title1 = CoderSonTrang - Ví dụ về Spring MVC  
 body.title2 = Hiển thị sách của sinh viên   
 
 body.form.your_name = Tên của bạn  
 body.form.your_list_of_book = Chỉnh sửa tập sách của bạn  
 body.form.button.submit = Gửi  

Mỗi đoạn văn bản trong file tài nguyên sẽ có một key tương ứng. Các file tài nguyên thuộc các ngôn ngữ khác nhau sẽ giống nhau về các key, chỉ khác nhau về nội dung đi kèm với key vì nó phụ thuộc vào từng ngôn ngữ. Ở trang jsp, ta lấy ra nội dung của các đoạn văn bản bằng việc gọi key của chúng, sau đó Spring sẽ lấy ra đoạn văn bản tương ứng với key trong ngôn ngữ đang được chọn. Điều này được minh họa cụ thể trong file index.jsp như sau:

index.jsp

 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
 <%@taglib prefix="form" uri="http://www.springframework.org/tags/form"%>  
 <%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>  
 <html>  
  <head><title><spring:message code="header.title"/> </title></head>  
  <body>  
       <c:if test="${param.lang == 'vi' }">  
            <a href="<spring:url value="/home?lang=vi"/>" style="color:red;">Vi</a>   
            <a href="<spring:url value="/home?lang=en"/>">En</a>  
       </c:if>  
       <c:if test="${param.lang != 'vi' }">  
            <a href="<spring:url value="/home?lang=vi"/>">Vi</a>  
            <a href="<spring:url value="/home?lang=en"/>" style="color:red;">En</a>   
       </c:if>  
   <h1><spring:message code="body.title1"/> </h1>  
   <h3><spring:message code="body.title2"/> </h3>  
   <form:form method="POST" action="submitStudentInfo" commandName="model">  
        <input type="hidden" name="lang" value="${param.lang }"/>  
        <spring:message code="body.form.your_name"/>: <c:out value="${model.name }"/>  
        <form:hidden path="name"/><br/><br/>  
        <spring:message code="body.form.your_list_of_book"/>:   
        <c:forEach items="${model.books}" var="book" varStatus="status">  
             <form:input path="books[${status.index}]"></form:input>  
        </c:forEach>  
        <input type="submit" value="<spring:message code="body.form.button.submit"/>"/>  
   </form:form>  
   
</body> </html>

Như đã thấy ở trên, để lấy ra đoạn văn bản, ta sử dụng thẻ <spring:message /> và chỉ ra key của đoạn văn bản bằng cách đặt giá trị cho thuộc tính code. Cũng trong trang jsp này, ta thêm hai đường link cho người dùng để có thể chọn ngôn ngữ là tiếng Việt hay tiếng Anh. Để ý chúng ta có thể thấy rằng các link sẽ có thêm tham số lang ở phía sau url của chúng.

Với việc sửa đổi như trên, khi chạy ví dụ của chúng ta, lần đầu tiên truy nhập ta có thể thấy ngôn ngữ hiển thị là tiếng Anh, đó là ngôn ngữ mặc định mà chúng ta đã chỉ ra trong file cấu hình như hình dưới đây:
i18n_3

Khi nhấp vào link Vi, ngôn ngữ hiển thị sẽ là tiếng Việt như hình dưới đây

i18n_4

Good luck!

Advertisements

One comment on “i18n trong Spring MVC

Trả lời

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Đăng xuất /  Thay đổi )

Google photo

Bạn đang bình luận bằng tài khoản Google Đăng xuất /  Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Đăng xuất /  Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Đăng xuất /  Thay đổi )

Connecting to %s