- 浏览: 304626 次
- 性别:
- 来自: 南京
最新评论
-
memorymyann:
不好意思我看错了
Java计算时间差 -
memorymyann:
好吧,网上很多方法一的,我不知道大家有验证过没有。我测试了下。 ...
Java计算时间差 -
ndzj981479673:
TonyLian 写道下这个包到WEB-INF/libs sp ...
org.springframework.web.servlet.DispatcherServlet -
Heart-wu:
com.jacob.com.ComFailException: ...
Jacob使用小结 -
wo4562658:
没有附件?getAnyCellStyle 这个方法,getHd ...
POI使用小结
如果应用系统是面向多种语言的,编程时就不得不设法解决国际化问题,包括操作界面的风格问题、提示和帮助语言的版本问题、界面定制个性化问题等。
由于Java语言具有平台无关、可移植性好等优点,并且提供了强大的类库,所以Java语言可以辅助我们解决上述问题。Java语言本身采用双字节字符编码,采用大汉字字符集,这就为解决国际化问题提供了很多方便。从设计角度来说,只要把程序中与语言和文化有关的部分分离出来,加上特殊处理,就可以部分解决国际化问题。在界面风格的定制方面,我们把可以参数化的元素,如字体、颜色等,存储在数据库里,以便为用户提供友好的界面;如果某些部分包含无法参数化的元素,那么我们可能不得不分别设计,通过有针对性的编码来解决具体问题。
Java类包
在用Java解决国际化问题的过程中,可能利用到的主要的类都是由java.util包提供的。该类包中相关的类有Locale、ResourceBundle、ListResourceBundle、PropertyResourceBundle等,其继承关系如下图所示。
其中各类提供的主要功能如下:
Locale:该类包含对主要地理区域的地域化特征的封装。其特定对象表示某一特定的地理、政治或文化区域。通过设定Locale,我们可以为特定的国家或地区提供符合当地文化习惯的字体、符号、图标和表达格式。例如,我们可以通过获得特定Locale下的Calendar类的实例,显示符合特定表达格式的日期。
ResourceBundle:该类是一个抽象类,需要通过静态方法ResourceBundle.getBundle()指定具体实现类或属性文件的基本名称。基本名称会协同指定的或默认的Locale类,决定具体调用的类或属性文件的唯一名称。例如:指定基本类或属性文件名称为TestBundle,而指定的Locale是CHINESE,那么最适合匹配的类名称为TestBundle_zh_CN.class,而最佳匹配属性文件名称为TestBundle_zh_CN.properties。按照Java Doc和相关文档的要求,如果该类或属性文件没有找到,系统会查找近似匹配(主文件名依次为TestBundle_zh和TestBundle的类或属性文件)。该类提供的getKeys()方法用于获得所有成员的键名,并提供handleGetObject方法获得指定键的对应元素。
ListResourceBundle:该类继承ResourceBundle类,主要是增加了一些便于操作的成分,但还是抽象类。如果希望使用类的方式实现具体的ResourceBundle,一般情况下最好继承这个类。
PropertyResourceBundle:该类也继承ResourceBundle类,可以实例化。该类的行为特征如同java.util.properties类,可以从输入流中获得具体属性对。
如果涉及日期和时间显示等问题时,可以利用java.text包以及java.util包中的TimeZone、SimpleTimeZone和Calendar等类进行辅助处理。
参数化解决方法
在具体应用时,可以把具体国家或地区特征中可以参数化的部分放在经过特殊命名的属性文件中,在确定具体的Locale后,通过PropertyResourceBundle类读取相应的属性文件,实现国际化特征。
使用PropertyResourceBundle类获得当地版本的国际化信息,部分代码如下:
……
public static final String BASE_PROP_FILE =
“DISP”;
public static final String SUFFIX =
“.properties”;
locale = Locale.getDefault();
String propFile = BASE_PROP_FILE + “_” + locale.toString()+ SUFFIX;
ResourceBundle rb;
try {
File file = new File(propFile);
if (file.exists()) {
is = new FileInputStream(file);
rb = new PropertyResourceBundle(is);
if (rb == null) System.out.println(“No Resource”);
}
} catch (IOException ioe) {
System.out.println(“Error open file named ” + propFile);
}
Enumeration e = rb.getKeys();
while (e.hasMoreElements()){
key = (String)e.nextElement();
value = (String)rb.handleGetObject(key);
System.out.println(“KEY: ” + key +
“\t\t Value: ” + value);
}
……
DISP_zh_TW.properties文件的具体内容如下:
Key1=\u53ef\u4ee5
Key2=\u64a4\u9500
等号后面是利用native2ascii程序转化后的繁体汉字,如果不进行转化,系统可能显示乱码。
处理提示和帮助
对于提示语言和帮助文件部分,可以把语言映射放在属性文件或者ListResourceBundle类的子类中。下面程序是一个Servlet,它通过接受客户端的选择,把特定语言和字符版本的信息返回到客户端。
……
public class ProcessServlet extends HttpServlet
{ //默认语言为中文
public static final String DEFAULT_LANGUAGE = “zh”;
//默认字符集为简体中文
public static final String DEFAULT_COUNTRY = “CN”;
public void service(HttpServletRequest req,
HttpServletResponse res) throws IOException, ServletException {
HttpSession session = req.getSession(true);
// 从客户端收到的指定语言和字符的参数应当与Sun公司相关规定一致
String lang = req.getParameter
(“language”);
String country = req.getParameter
(“country”);
if (lang == null)
{
//如果没有收到参数,就试图从Session里获得
lang = (String) session.getAttribute
(“language”);
country = (String) session.getAttribute
(“country”)
} else {
session.setAttribute(“language”, lang);
session.setAttribute(“country”, country);
}
if (lang == null)
{
//如果无法从上述手段得到语言和字符信息,就使用默认值
lang = DEFAULT_LANGUAGE;
country = DEFAULT_COUNTRY
session.setAttribute(“language”, lang);
session.setAttribute(“country”, country);
}
Locale locale = null;
ResourceBundle bundle = null;
try {
locale = new Locale(lang, country);
} catch (Exception e) {
System.out.println(“No locale with” +
country + “_” + lang);
locale = Locale.getDefault();
}
try {
bundle = ResourceBundle.getBundle(
“DisplayList”, locale);
} catch( MissingResourceException e) {
System.out.println( “No resources available for locale ” + locale);
bundle = ResourceBundle.getBundle
(“DisplayList”, Locale.US);
}
res.setContentType(“text/html”);
PrintWriter out = res.getWriter();
out.println(“”);
out.println(“”);
String title = bundle.getString(“title”);
String welcome =bundle.getString
(“welcome”);
String notice = bundle.getString(“notice”);
out.println(“”);
out.println(“”);
out.println(“white\“>”);
out.println(“
” + welcome +
“
”);
out.println(“
”);
out.println(“” + notice +
“”);
out.println(“”);
out.println(“”);
}
}
上述Servlet使用的属性文件(DisplayList_zh_CN.
properties)内容如下:
title=中文版
welcome=这是简体中文版面
notice=简体中文测试成功
注意:该文件直接采用了中文,而不是经过转化的Unicode编码,这是由于大多数Web服务器不需要上述转化。
在实际使用中,如果Web服务器支持Servlet 2.3规范(如jakarta-tomcate 4.0),那么上面提到的Servlet应当稍加改变,以作为其他Servlet的处理器使用。另外,如果把ResourceBundle的特定版本存放在无状态会话Bean中,就可以在一定程度上提高程序效率。
小 结
笔者在实际测试中发现了如下问题,其中部分问题得到了解决:
1. 对于显示字符出现乱码的问题,如果是通过属性文件实现国际化解决方案,那么可能是直接在属性文件中写入了非标准ASCII文字。解决方法是利用JDK提供的工具native2ascii.exe扫描所有属性文件,用扫描结果覆盖原有文件内容。如果我们是利用类文件实现转换方案,那么需要重新编译相关类文件,并在编译时指定编码集。例如,编译使用国标码的类文件,采用的编译命令如下:
javac -encoding GB2312 your_java_file
2. 虽然Sun宣称,在ResourceBundle类的实例化过程中,该类会查找与指定的基础类绝对匹配和尽量与指定的Locale属性相匹配的类。例如:如果我们指定ResourceBundle基础类为TestBundle,而Locale中指定使用zh_CN(中国大陆地区简体中文),那么如果系统找不到TestBundle_zh_CN,系统应当顺次查找TestBundle_zh、TestBundle。但是笔者在系统开发过程中发现,该匹配没有产生任何实际效果。
笔者的测试平台是Windows 2000 Server,没有配置任何Service Pack,使用的JDK版本是1.3.0版本。笔者试图通过查看JDK目录下src.jar中附带的源码找到引起问题的原因,但是发现有关的操作被封装在sun.misc包中,而src.jar文件没有提供该包中任何类的源码。本文把这个问题提出来,希望与有关开发人员一起探讨。
由于Java语言具有平台无关、可移植性好等优点,并且提供了强大的类库,所以Java语言可以辅助我们解决上述问题。Java语言本身采用双字节字符编码,采用大汉字字符集,这就为解决国际化问题提供了很多方便。从设计角度来说,只要把程序中与语言和文化有关的部分分离出来,加上特殊处理,就可以部分解决国际化问题。在界面风格的定制方面,我们把可以参数化的元素,如字体、颜色等,存储在数据库里,以便为用户提供友好的界面;如果某些部分包含无法参数化的元素,那么我们可能不得不分别设计,通过有针对性的编码来解决具体问题。
Java类包
在用Java解决国际化问题的过程中,可能利用到的主要的类都是由java.util包提供的。该类包中相关的类有Locale、ResourceBundle、ListResourceBundle、PropertyResourceBundle等,其继承关系如下图所示。
其中各类提供的主要功能如下:
Locale:该类包含对主要地理区域的地域化特征的封装。其特定对象表示某一特定的地理、政治或文化区域。通过设定Locale,我们可以为特定的国家或地区提供符合当地文化习惯的字体、符号、图标和表达格式。例如,我们可以通过获得特定Locale下的Calendar类的实例,显示符合特定表达格式的日期。
ResourceBundle:该类是一个抽象类,需要通过静态方法ResourceBundle.getBundle()指定具体实现类或属性文件的基本名称。基本名称会协同指定的或默认的Locale类,决定具体调用的类或属性文件的唯一名称。例如:指定基本类或属性文件名称为TestBundle,而指定的Locale是CHINESE,那么最适合匹配的类名称为TestBundle_zh_CN.class,而最佳匹配属性文件名称为TestBundle_zh_CN.properties。按照Java Doc和相关文档的要求,如果该类或属性文件没有找到,系统会查找近似匹配(主文件名依次为TestBundle_zh和TestBundle的类或属性文件)。该类提供的getKeys()方法用于获得所有成员的键名,并提供handleGetObject方法获得指定键的对应元素。
ListResourceBundle:该类继承ResourceBundle类,主要是增加了一些便于操作的成分,但还是抽象类。如果希望使用类的方式实现具体的ResourceBundle,一般情况下最好继承这个类。
PropertyResourceBundle:该类也继承ResourceBundle类,可以实例化。该类的行为特征如同java.util.properties类,可以从输入流中获得具体属性对。
如果涉及日期和时间显示等问题时,可以利用java.text包以及java.util包中的TimeZone、SimpleTimeZone和Calendar等类进行辅助处理。
参数化解决方法
在具体应用时,可以把具体国家或地区特征中可以参数化的部分放在经过特殊命名的属性文件中,在确定具体的Locale后,通过PropertyResourceBundle类读取相应的属性文件,实现国际化特征。
使用PropertyResourceBundle类获得当地版本的国际化信息,部分代码如下:
……
public static final String BASE_PROP_FILE =
“DISP”;
public static final String SUFFIX =
“.properties”;
locale = Locale.getDefault();
String propFile = BASE_PROP_FILE + “_” + locale.toString()+ SUFFIX;
ResourceBundle rb;
try {
File file = new File(propFile);
if (file.exists()) {
is = new FileInputStream(file);
rb = new PropertyResourceBundle(is);
if (rb == null) System.out.println(“No Resource”);
}
} catch (IOException ioe) {
System.out.println(“Error open file named ” + propFile);
}
Enumeration e = rb.getKeys();
while (e.hasMoreElements()){
key = (String)e.nextElement();
value = (String)rb.handleGetObject(key);
System.out.println(“KEY: ” + key +
“\t\t Value: ” + value);
}
……
DISP_zh_TW.properties文件的具体内容如下:
Key1=\u53ef\u4ee5
Key2=\u64a4\u9500
等号后面是利用native2ascii程序转化后的繁体汉字,如果不进行转化,系统可能显示乱码。
处理提示和帮助
对于提示语言和帮助文件部分,可以把语言映射放在属性文件或者ListResourceBundle类的子类中。下面程序是一个Servlet,它通过接受客户端的选择,把特定语言和字符版本的信息返回到客户端。
……
public class ProcessServlet extends HttpServlet
{ //默认语言为中文
public static final String DEFAULT_LANGUAGE = “zh”;
//默认字符集为简体中文
public static final String DEFAULT_COUNTRY = “CN”;
public void service(HttpServletRequest req,
HttpServletResponse res) throws IOException, ServletException {
HttpSession session = req.getSession(true);
// 从客户端收到的指定语言和字符的参数应当与Sun公司相关规定一致
String lang = req.getParameter
(“language”);
String country = req.getParameter
(“country”);
if (lang == null)
{
//如果没有收到参数,就试图从Session里获得
lang = (String) session.getAttribute
(“language”);
country = (String) session.getAttribute
(“country”)
} else {
session.setAttribute(“language”, lang);
session.setAttribute(“country”, country);
}
if (lang == null)
{
//如果无法从上述手段得到语言和字符信息,就使用默认值
lang = DEFAULT_LANGUAGE;
country = DEFAULT_COUNTRY
session.setAttribute(“language”, lang);
session.setAttribute(“country”, country);
}
Locale locale = null;
ResourceBundle bundle = null;
try {
locale = new Locale(lang, country);
} catch (Exception e) {
System.out.println(“No locale with” +
country + “_” + lang);
locale = Locale.getDefault();
}
try {
bundle = ResourceBundle.getBundle(
“DisplayList”, locale);
} catch( MissingResourceException e) {
System.out.println( “No resources available for locale ” + locale);
bundle = ResourceBundle.getBundle
(“DisplayList”, Locale.US);
}
res.setContentType(“text/html”);
PrintWriter out = res.getWriter();
out.println(“”);
out.println(“”);
String title = bundle.getString(“title”);
String welcome =bundle.getString
(“welcome”);
String notice = bundle.getString(“notice”);
out.println(“”);
out.println(“”);
out.println(“white\“>”);
out.println(“
” + welcome +
“
”);
out.println(“
”);
out.println(“” + notice +
“”);
out.println(“”);
out.println(“”);
}
}
上述Servlet使用的属性文件(DisplayList_zh_CN.
properties)内容如下:
title=中文版
welcome=这是简体中文版面
notice=简体中文测试成功
注意:该文件直接采用了中文,而不是经过转化的Unicode编码,这是由于大多数Web服务器不需要上述转化。
在实际使用中,如果Web服务器支持Servlet 2.3规范(如jakarta-tomcate 4.0),那么上面提到的Servlet应当稍加改变,以作为其他Servlet的处理器使用。另外,如果把ResourceBundle的特定版本存放在无状态会话Bean中,就可以在一定程度上提高程序效率。
小 结
笔者在实际测试中发现了如下问题,其中部分问题得到了解决:
1. 对于显示字符出现乱码的问题,如果是通过属性文件实现国际化解决方案,那么可能是直接在属性文件中写入了非标准ASCII文字。解决方法是利用JDK提供的工具native2ascii.exe扫描所有属性文件,用扫描结果覆盖原有文件内容。如果我们是利用类文件实现转换方案,那么需要重新编译相关类文件,并在编译时指定编码集。例如,编译使用国标码的类文件,采用的编译命令如下:
javac -encoding GB2312 your_java_file
2. 虽然Sun宣称,在ResourceBundle类的实例化过程中,该类会查找与指定的基础类绝对匹配和尽量与指定的Locale属性相匹配的类。例如:如果我们指定ResourceBundle基础类为TestBundle,而Locale中指定使用zh_CN(中国大陆地区简体中文),那么如果系统找不到TestBundle_zh_CN,系统应当顺次查找TestBundle_zh、TestBundle。但是笔者在系统开发过程中发现,该匹配没有产生任何实际效果。
笔者的测试平台是Windows 2000 Server,没有配置任何Service Pack,使用的JDK版本是1.3.0版本。笔者试图通过查看JDK目录下src.jar中附带的源码找到引起问题的原因,但是发现有关的操作被封装在sun.misc包中,而src.jar文件没有提供该包中任何类的源码。本文把这个问题提出来,希望与有关开发人员一起探讨。
发表评论
-
synchronized(this)的一些理解
2011-12-06 18:58 1013对synchronized(this)的 ... -
Comparator和Comparable在排序中的应用
2011-07-30 11:21 899当需要排序的集合或数组不是单纯的数字型时,通常可以使用Co ... -
如何将文件中Base64进制数据生成X509证书
2010-12-16 19:50 2765byte[] ciphertext1 = new BASE64 ... -
Java相关数字签名技术纪要
2010-12-16 18:59 1210一:需要包含的包 ... -
jdom通过string生产xml文档
2010-12-09 10:50 1080生产xml文档: XMLOutputter outpu ... -
Tomcat支持Https访问
2010-11-10 20:01 3193用Tomcat来配置SSL主要有下面这么两大步骤: 一、生成证 ... -
一个tomcat配置多个端口
2010-10-19 18:43 3078第一步、修改server.xml[..\Tomcat 6.0\ ... -
Servlet上传文件及发送HTTP请求至Servet上传文件。
2010-08-12 18:30 1660Servlet接受HTTP消息,解析内容并输出至文件中 // ... -
如何在工程指定目录下保存文件。
2010-08-11 18:59 12061:Servlet中 String fileDir ... -
各进制基本概念。
2010-07-30 12:26 1156二进制: 二进制是逢2进位的进位制,0、 ... -
Junit小结
2010-07-20 08:58 657一 几个常用注释 @Before 被它注释的方法, ... -
JMockit_UT小结
2010-07-15 16:11 11551:模拟方法抛出异常 fin ... -
如何将当前时间延迟至指定的年、月、日后日期。
2010-06-23 19:27 1031Calendar cale = Calenda ... -
tomcat添加gzip功能
2010-03-04 15:24 2018在文件tomcat/conf/server.xml 中添加红 ... -
HttpClient笔记
2010-01-16 20:03 3325背景:因为想写一个测试tomcat连接的程序,就试试自已去构造 ... -
ThreadLocal知识
2009-11-14 21:57 2704首先,ThreadLocal 不是用来解决共享对象的多线程访问 ... -
一个不错的JDBC连接池教程(带具体例子)
2009-06-11 21:17 1255关键字: jdbc 1.前言 数据库应用,在许多软件系统中 ... -
Java程序对图片的各种处理
2009-06-11 21:12 1621关键字: 缩放图像、图像切割、图像类型转换、彩色转为黑白 Ja ... -
Java计算时间差
2009-06-11 21:10 5839比如:现在是2004-03-26 13:31:40 ... -
Unable to instantiate Action(关于struts2.0异常)
2009-05-17 20:39 7795[ERROR] - [2009-03-12 14:27:59] ...
相关推荐
为了解决`SimpleDateFormat`的线程安全问题,Java 8引入了`java.time`包,这是新的日期时间API,包含了`LocalDate`、`LocalTime`、`LocalDateTime`、`ZonedDateTime`等类,它们提供了更强大、更安全、更易于使用的...
Java作为一种广泛使用的编程语言,提供了强大的国际化支持。本篇将深入探讨Java中实现国际化的必备工具以及相关的编码转换问题。 一、Java中的国际化 1. **资源绑定文件(Properties文件)** 在Java中,我们通常...
通过以上方法,开发者可以有效地解决Java国际化过程中遇到的中文乱码问题。`BundleEditor` 提供的工具集可以简化这个过程,提高开发效率,并确保应用程序在全球范围内提供一致且正确的用户体验。为了充分利用这个...
此外,还可以考虑使用Spring框架的国际化支持,它可以更方便地集成到大型项目中,提供基于注解的国际化解决方案。Spring的`MessageSource`接口和`@MessageSource`注解可以帮助我们在控制器或服务层直接注入本地化...
Java国际化的工具propedit是Java开发中用于处理国际化(i18n)和本地化(l10n)过程的一款实用程序。在Java应用程序中,为了支持不同地区的用户,我们需要提供多语言支持,这就涉及到了国际化和本地化。propedit正是...
总的来说,这个工具包可能提供了一套完整的解决方案,包括Java和本地代码层面的国际化支持,以及使用`gettext`工具进行资源文件管理和翻译的工作流程。对于开发跨语言应用的Java开发者来说,这是一份非常实用的资源...
该项目为基于SpringBoot框架开发的Java后端国际化解决方案源码,集成了33个文件,包括11个Java源文件、10个PNG图片文件、4个属性文件、3个XML配置文件、1个Git忽略文件、1个许可证文件、1个Markdown文件、1个SQL文件...
### 关于JAVA国际化的问题资料 #### 一、JAVA国际化的概念与重要性 JAVA国际化(Internationalization,简称I18N)是指设计和开发应用程序时,使其能够在不同的语言和文化环境中运行,而无需进行代码修改。它关注...
本文详细介绍了Java中的国际化操作,包括如何使用`Locale`类来表示具体的地理位置信息,如何利用`ResourceBundle`类加载和管理资源文件,以及如何避免硬编码带来的问题。通过合理的资源文件管理和代码设计,可以使...
Java反序列化安全漏洞是一种严重的安全威胁,...总之,Java反序列化安全漏洞是一个广泛存在且危害严重的安全问题。只有通过不断的关注安全动态、实施有效的防御措施以及定期更新和打补丁,才能确保Java应用的安全运行。
如果应用系统是面向多种语言的,编程时就不得不设法解决国际化问题,包括操作界面的风格问题、提示和帮助语言的版本问题...Java语言本身采用双字节字符编码,采用大汉字字符集,这就为解决国际化问题提供了很多方便.zip
如果应用系统是面向多种语言的,编程时就不得不设法解决国际化问题,包括操作界面的风格问题、提示和帮助语言的版本问题...Java语言本身采用双字节字符编码,采用大汉字字符集,这就为解决国际化问题提供了很多方便.zip
java程序实现国际化,解决乱码问题!这是实现的程序代码,稍后会上传配置文件
- ASP.NET使用资源文件(`.resx`)和 globalization 属性来实现国际化,与Java的ResourceBundle类似。 - C#中也有`ResourceManager`类用于加载和访问资源,同时.NET框架提供了`CultureInfo`类来处理Locale。 - ...
本文将深入探讨解决Struts中文问题及国际化问题的终极方案,确保不同地区和语言环境下的用户都能正确、流畅地使用Web应用。 #### 核心策略:UTF-8编码与资源文件管理 - **统一采用UTF-8编码**:所有HTML和JSP页面...
在Java Web开发中,实现国际化是一项重要的任务,它允许应用程序为不同地区的用户提供本地化的界面和内容。"JAVA Web实现国际化插件"就是这样一个工具,它旨在简化这一过程,提供便捷的语言转换功能。以下是对该插件...
在编程领域,实现一个国际象棋游戏是一种经典的挑战,它涉及到复杂的逻辑和算法设计。本项目以JAVA作为编程语言,构建了一个人与人...通过这个项目,开发者不仅可以深入理解JAVA编程,还能提升逻辑思维和问题解决能力。
6. **国际化(i18n)**:在处理多语言环境时,使用`java.text`包中的`Format`和`MessageFormat`类,它们支持不同语言和地区的字符编码。 7. **XML解析**:处理XML文件时,需关注XML声明中的编码信息,如`...
Java 中文问题解决大全主要关注的是在Java开发中如何处理中文字符编码的问题,确保程序在不同操作系统环境下能够正确处理和显示中文。中文乱码问题通常出现在输入、输出、文件读写以及与数据库交互的过程中。以下是...