浅谈基于ExtJS的AJAX程序中i18n的实现

前两天在我的Gajax框架中实现了i18n
先来几张图

1. 中文界面

 

 

 

2. 英文界面

 

 

 

3. 界面语言设置窗口

 

 

 

实现步骤如下:

1. 写一个LocaleServlet

package org.gajaxframework.i18n;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.gajaxframework.context.GajaxContext;

/**
 * Gajax Locale Servlet
 * 
 * @author Sam Chen
 * @version 1.0 05/24/2008 11:54
 */
public class LocaleServlet extends HttpServlet {
	
	private static String DEFAULT_LANGUAGE = "EN";
	private static String localeConfigLocation = "/WEB-INF/locale";
	
	private static Map<String, String> LOCALES = new HashMap<String, String>();
	
	private static Log log = LogFactory.getLog(LocaleServlet.class);

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
//	    String language = (String) request.getParameter("language");
	    String pathInfo = request.getPathInfo();
	    String language = null == pathInfo ? "" : pathInfo.substring(pathInfo.lastIndexOf("/") + 1);
		
	    if (null == language || "".equals(language.trim())) {
	    	// FIXME: get language setting from the user's customized settings
	    	language = "EN";
	    }
	    
	    language = (null == language ? DEFAULT_LANGUAGE : language.toUpperCase());

	    String resource = LOCALES.get(language);
	    if (null == resource) {
	    	log.warn("No locale resource found for language '" + language + "'. Defaults to '" + DEFAULT_LANGUAGE + "'");
	    	resource = LOCALES.get(DEFAULT_LANGUAGE);
	    } else {
	    	log.info("Locale resource found for language '" + language + "'.");
	    }
	    
	    printResource(response, resource);
	    
	}
	
	/**
	 * print locale resource to the client
	 * 
	 * @param response
	 */
	private void printResource(HttpServletResponse response, String resource) throws IOException {
		response.setContentType("text/html;charset=utf-8");
		PrintWriter writer = response.getWriter();
		writer.print(resource);
		writer.flush();
		writer.close();
	}

	// ====================== initialization ======================
	@Override
	public void init(ServletConfig config) throws ServletException {
		
		String customizedDEFAULT_LANGUAGE = config.getInitParameter("DEFAULT_LANGUAGE");
		String customizedlocaleConfigLocation = config.getInitParameter("localeConfigLocation");

		// override the default(hard-coded) configurations if there're customized configurations
		if (null != customizedDEFAULT_LANGUAGE) {
			DEFAULT_LANGUAGE = customizedDEFAULT_LANGUAGE;
		}
		if (null != customizedlocaleConfigLocation) {
			localeConfigLocation = customizedlocaleConfigLocation;
		}
		
		loadLocales(localeConfigLocation);
	}

	/**
	 * load all the locales and put 'em to the map
	 * @param localeConfigLocation
	 */
	private void loadLocales(String localeConfigLocation) {
		localeConfigLocation = GajaxContext.REAL_PATH + localeConfigLocation;
		File localeConfigFolder = new File(localeConfigLocation);
		File[] localeFiles = localeConfigFolder.listFiles();
		
		for (int i = 0, l = localeFiles.length; i < l; i++) {
			File localeFile = localeFiles[i];
			String fileName = localeFile.getName();
			if (!fileName.endsWith(".properties") || fileName.endsWith(".original.properties")) {
				continue;
			}
			String language = fileName.substring(fileName.indexOf("_") + 1, fileName.indexOf(".properties"));
			
			InputStream is = null;
			try {
				is = new FileInputStream(localeFile);
				Properties properties = new Properties();
				properties.load(is);
				String json = conver2Json(properties);
				LOCALES.put(language.toUpperCase(), json);
				log.info("Locale resource for language '" + language + "' loaded:\n" + json);
			} catch (FileNotFoundException fnfe) {
				;
			} catch (IOException ioe) {
				;
			} finally {
				try {
					is.close();
				} catch (Exception x) {}
			}
		}
	

	}
	
	/**
	 * convert key-value pairs to JSON format
	 * @param properties
	 * @return
	 */
	private String conver2Json(Properties properties) {
		StringBuilder sb = new StringBuilder();
		sb.append("GajaxLocale={\n");
		sb.append("    'PROJECT_NAME':'MyDesktop',\n");
		sb.append("    'PROJECT_VERSION':'1.0 Beta',\n");
		sb.append("    'SERVLET_CONTEXT_NAME':").append("'").append(GajaxContext.SERVLET_CONTEXT_NAME).append("',\n");
		
		List<String> keys = new ArrayList<String>();
		for (Enumeration<Object> em = properties.keys(); em.hasMoreElements();) {
			String key = (String) em.nextElement();
			keys.add(key);
		}
		Collections.sort(keys, new Comparator<String>() {
			public int compare(String k1, String k2) {
				return k1.compareTo(k2);
			}
		});
		
		for (int i = 0, l = keys.size(); i < l; i++) {
			String key = keys.get(i);
			String value = properties.getProperty(key);
			String suffix = i == l - 1 ? "};" : ",";
			
			if (null == value || "".equals(value.trim()) || "null".equalsIgnoreCase(value.trim())) {
				sb.append("    '").append(key).append("'").append(":").append("null").append(suffix).append("\n");
			} else {
				sb.append("    '").append(key).append("'").append(":").append("'").append(value).append("'").append(suffix).append("\n");
			}
		}
		
		return sb.toString();
	}
	
}

  为了得到中文Locale资源文件对应的UTF-8编码的文件,写个bat来调用%JAVA_HOME%/bin/native2ascii.exe

@echo off
                                         
echo ==============================================
echo Native2Ascii Utility
echo Author Sam Chen, Senior Software Engineer, GRS
echo Version 1.0 05/24/2008 11:23
echo ==============================================

set CURRENT_DIR=%cd%
echo Current DIR is %CURRENT_DIR%
cd ../workspace/MyDesktop/WEB-INF/locale
set CURRENT_DIR=%cd%
echo Current DIR changed to %CURRENT_DIR%
native2ascii.exe -encoding UTF-8 ./Gajax_zh.original.properties ./Gajax_zh.properties
echo Command 'native2ascii.exe -encoding UTF-8 ./Gajax_zh.original.properties ./Gajax_zh.properties' executed successfully
@pause

在web.xml文件中配置这个serlet

<servlet>
        <servlet-name>localeServlet</servlet-name>
        <servlet-class>org.gajaxframework.i18n.LocaleServlet</servlet-class>
        <init-param>
            <param-name>DEFAULT_LANGUAGE</param-name>
            <param-value>EN</param-value>
        </init-param>
        <init-param>
            <param-name>localeConfigLocation</param-name>
            <param-value>/WEB-INF/locale</param-value>
        </init-param>
        <load-on-startup>0</load-on-startup>
</servlet>
	
<servlet-mapping>
        <servlet-name>localeServlet</servlet-name>
        <url-pattern>/jslib/i18n/GajaxLocale/*</url-pattern>
</servlet-mapping>

2. html文件中用script标签下载locale资源

<!-- i18n resources -->
<script type="text/javascript" src="jslib/i18n/GajaxLocale/zh" charset="utf-8"></script>

注意这个script标签应该排在最前头,以保证locale资源对后续javascript可用

3. 再来个helper -- locale.js

/**
 * GRS.framework.data.Locale
 * @author Sam Chen
 * @version 1.0 11/21/2007 21:22
 * @version 1.0 05/24/2008 19:51 
 * (replaced hard-coded locale object with the JSON object downloaded from the server side)
 */
Ext.namespace("GRS.framework.data");
GRS.framework.data.Locale = function(M) {
   this.map = M || {}
};
Ext.extend(GRS.framework.data.Locale, Ext.util.Observable, {
   get : function(key) {
      var value = this.map[key] || (key + ' not found!'); 
      if(arguments.length > 1 && value.indexOf('{') >= 0) {
         value = new Ext.Template(value).apply(Array.prototype.slice.call(arguments, 1))
      }
      return value
   }
});

// GajaxLocale is a JSON object downloaded from the server side
var locale = new GRS.framework.data.Locale(GajaxLocale);

// shortcut for the method locale.get
$ = locale.get.createDelegate(locale);

4. html文件如下

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>MyDesktop App</title>

    <link rel="stylesheet" type="text/css" href="jslib/ext-2.1/resources/css/ext-all.css" />
    <link rel="stylesheet" type="text/css" href="resources/css/icons/icons.css" />
    
    <!-- i18n resources -->
    <script type="text/javascript" src="jslib/i18n/GajaxLocale/zh" charset="utf-8"></script>
 	
    <script type="text/javascript" src="jslib/ext-2.1/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="jslib/ext-2.1/ext-all.js"></script>
    
    <script type="text/javascript" src="jslib/grsframework/data/Locale.js"></script>

	<!-- DESKTOP -->
	<script type="text/javascript" src="jslib/desktop/core/StartMenu.js"></script>
	<script type="text/javascript" src="jslib/desktop/core/TaskBar.js"></script>
	<script type="text/javascript" src="jslib/desktop/core/Desktop.js"></script>
	<script type="text/javascript" src="jslib/desktop/core/App.js"></script>
	<script type="text/javascript" src="jslib/desktop/core/Module.js"></script>
	<script type="text/javascript" src="jslib/desktop/core/DesktopConfig.js"></script>

	<!-- DESKTOP HELPERS -->
	<script type="text/javascript" src="jslib/desktop/helpers/color-picker/color-picker.ux.js"></script>
	
	<link rel="stylesheet" type="text/css" href="jslib/desktop/helpers/color-picker/color-picker.ux.css" />
	<script type="text/javascript" src="jslib/desktop/helpers/preferences/Preferences.js"></script>
	<link rel="stylesheet" type="text/css" href="jslib/desktop/helpers/preferences/preferences.css" />
	
	<!-- MODULES -->
	<script type="text/javascript" src="jslib/modules/layout-window/js/layout-window.js"></script>
	<script type="text/javascript" src="jslib/modules/docs/js/docs.js"></script>
	<link rel="stylesheet" type="text/css" href="jslib/modules/docs/css/docs.css" />
	
	<!-- DESKTOP STYLES -->
	<link rel="stylesheet" type="text/css" href="jslib/ext-2.1/examples/desktop/css/desktop.css" />
	<link rel="stylesheet" type="text/css" href="resources/css/desktop-sam.css" />
</head>
<body id="desktop-body" scroll="no" background="resources/wallpapers/blue-swirl.jpg">
</body>
</html>

 谨发此文,以抛砖引玉。

你可能感兴趣的:(JavaScript,Ajax,servlet,css,ext)