struts中文解决方案

Struts完全中文显示解决方案

  [背景知识]

本背景知识参考了IBM DeveloperWorks 中国网站提供的《JSP/Servlet 中的汉字编码问题

1.问题的起源

  每个国家(或区域)都规定了计算机信息交换用的字符编码集,如美国的 ASCII,中国的 GB2312-80,日本的 JIS 等,作为该国家/区域内信息处理的基础,有着统一编码的重要作用。字符编码集按长度分为 SBCS(单字节字符集),DBCS(双字节字符集)两大类。早期的软件(尤其是操作系统),为了解决本地字符信息的计算机处理,出现了各种本地化版本(L10N),为了区分,引进了 LANG,Codepage 等概念。但是由于各个本地字符集代码范围重叠,相互间信息交换困难;软件各个本地化版本独立维护成本较高。因此有必要将本地化工作中的共性抽取出来,作一致处理,将特别的本地化处理内容降低到最少。这也就是所谓的国际化(I18N)。各种语言信息被进一步规范为 Locale 信息。处理的底层字符集变成了几乎包含了所有字形的 Unicode。

  现在大部分具有国际化特征的软件核心字符处理都是以 Unicode 为基础的,在软件运行时根据当时的 Locale/Lang/Codepage 设置确定相应的本地字符编码设置,并依此处理本地字符。在处理过程中需要实现 Unicode 和本地字符集的相互转换,甚或以 Unicode 为中间的两个不同本地字符集的相互转换。这种方式在网络环境下被进一步延伸,任何网络两端的字符信息也需要根据字符集的设置转换成可接受的内容。

  java 语言内部是用 Unicode 表示字符的,遵守 Unicode V2.0。Java 程序无论是从/往文件系统以字符流读/写文件,还是往 URL 连接写 HTML 信息,或从 URL 连接读取参数值,都会有字符编码的转换。这样做虽然增加了编程的复杂度,容易引起混淆,但却是符合国际化的思想的。

  从理论上来说,这些根据字符集设置而进行的字符转换不应该产生太多问题。而事实是由于应用程序的实际运行环境不同,Unicode 和各个本地字符集的补充、完善,以及系统或应用程序实现的不规范,转码时出现的问题时时困扰着程序员和用户。

2.GB2312-80,GBK,GB18030-2000 汉字字符集

  其实解决 java 程序中的汉字编码问题的方法往往很简单,但理解其背后的原因,定位问题,还需要了解现有的汉字编码和编码转换。

  GB2312-80 是在国内计算机汉字信息技术发展初始阶段制定的,其中包含了大部分常用的一、二级汉字,和 9 区的符号。该字符集是几乎所有的中文系统和国际化的软件都支持的中文字符集,这也是最基本的中文字符集。其编码范围是高位0xa1-0xfe,低位也是 0xa1-0xfe;汉字从 0xb0a1 开始,结束于 0xf7fe;

  GBK 是 GB2312-80 的扩展,是向上兼容的。它包含了 20902 个汉字,其编码范围是 0x8140-0xfefe,剔除高位 0x80 的字位。其所有字符都可以一对一映射到 Unicode 2.0,也就是说 java 实际上提供了 GBK 字符集的支持。这是现阶段 Windows 和其它一些中文操作系统的缺省字符集,但并不是所有的国际化软件都支持该字符集,感觉是他们并不完全知道 GBK 是怎么回事。值得注意的是它不是国家标准,而只是规范。随着 GB18030-2000国标的发布,它将在不久的将来完成它的历史使命。

  GB18030-2000(GBK2K) 在 GBK 的基础上进一步扩展了汉字,增加了藏、蒙等少数民族的字形。GBK2K 从根本上解决了字位不够,字形不足的问题。它有几个特点:

  ●它并没有确定所有的字形,只是规定了编码范围,留待以后扩充。

  ●编码是变长的,其二字节部分与 GBK 兼容;四字节部分是扩充的字形、字位,其编码范围是首字节 0x81-0xfe、二字节0x30-0x39、三字节 0x81-0xfe、四字节0x30-0x39。

  ●它的推广是分阶段的,首先要求实现的是能够完全映射到 Unicode 3.0 标准的所有字形。

  ●它是国家标准,是强制性的。

  现在还没有任何一个操作系统或软件实现了 GBK2K 的支持,这是现阶段和将来汉化的工作内容。

 

3.Struts程序设计中常见的 encoding 问题的

(1)JSP页面中文显示问题;

(2)中文资源显示问题

(3)数据库数据中文显示

(4)表单提交参数中的中文解决问题

JavaWebStudio中,提供完全的中文解决方案,上述所有问题都是自动解决的。

 

[实现方案]

Action中调用通用方法:docFileName = timeString + "_" +
            new String(file.getFileName().getBytes("gbk"),
                       System.getProperty("file.encoding"));

1、JSP页面中文显示问题:

   在JavaWebStudio中,新建JSP文件时,自己加入如下代码:

<%@ page contentType="text/html;charset=GB2312" %>

这样JSP页面上的中文就可以正常显示了。

例如,在新建文件时,通过采单或用鼠标点击文件管理器栏右键,然后选择“新建文件”或“新建立专用文件”下图所示:

 

在新建文件对话框中选择要建立的文件类型,这里选择“JSP文件”,输入文件名:

生成的new.jsp文件内容如下:

<%@ page contentType="text/html;charset=GB2312" %>

<html>

<head>

<title>type1</title>

</head>

<body>

<h1>type1</h1>

</body>

</html>

 

其实,“新建文件”和“新建立专用文件”都是从模板里拷贝过来的。“新建文件”中建立的文件内容与/bin/模板/Jave Web 项目下的“空的普通JSP模板”中newfile目录的文件内容对应,“新建立专用文件”中建立的文件内容与/bin/模板/Jave Web 项目下的本项目模板中newfile目录的文件内容对应。所以,用户可根据自己的需要对这些文件的内容进行修改,同时还可自己添加别的类型的文件模板。

2、中文资源显示问题:

  在JavaWebStudio中,默认的中文资源文件名是“ApplicationResources_ch.properties”,用户先将中文资源定入文件“ApplicationResources.properties”

然后选择工具条的“资源文件编码转换”键或选择“运行”菜单上的“资源文件编码转换”项,即可实现编码转换功能。过程如下图所示:

用户先把所有的中文资源写在ApplicationResources.properties中,完成后再生成新中文的资源文件是ApplicationResources_ch.properties,这里中文资源文件也可改成其它名字,通过是ApplicationResources_cn.properties。

3、数据库数据中文显示问题:

  在JavaWebStudio中建立Struts项目时,自动加入了编码转换设置过滤器。

  可见在JavaWebStudio中,不需编程人员编写任何代码,仅仅点击一个资源文件编码转换键即可完全解决Struts中文显示问题。

过滤器SetCharacterEncodingFilter.java代码如下:

package emptyprj.filters;

import javax.servlet.*;

import java.io.IOException;

public class SetCharacterEncodingFilter implements Filter {

protected String encoding = null;

protected FilterConfig filterConfig = null;

protected boolean ignore = true;

public void destroy() {

this.encoding = null;

this.filterConfig = null;

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain)

throws IOException, ServletException {

if (ignore || (request.getCharacterEncoding() == null)) {

String encoding = selectEncoding(request);

if (encoding != null)

request.setCharacterEncoding(encoding);

}

chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

this.encoding = filterConfig.getInitParameter("encoding");

String value = filterConfig.getInitParameter("ignore");

if (value == null)

this.ignore = true;

else if (value.equalsIgnoreCase("true"))

this.ignore = true;

else if (value.equalsIgnoreCase("yes"))

this.ignore = true;

else

this.ignore = false;

}

protected String selectEncoding(ServletRequest request) {

return (this.encoding);

}

}//EOC

过滤器在web.xml中配置,配置方法如下:

<filter>

    <filter-name>Set Character Encoding</filter-name>

    <filter-class>emptyprj.filters.SetCharacterEncodingFilter</filter-class>

    <init-param>

        <param-name>encoding</param-name>

        <param-value>GB2312</param-value>

    </init-param>

    <init-param>

        <param-name>ignore</param-name>

        <param-value>true</param-value>

    </init-param>

</filter>

<filter-mapping>

    <filter-name>Set Character Encoding</filter-name>

    <servlet-name>action</servlet-name>

</filter-mapping>

 

4、表单提交参数中的中文解决问题:

例如提交下面的表单,http://localhost:8080/Logon/UserEditAction.do? expression=普通用户。

Action中读取参数expression时,用下面的句子:

String expression=request.getParameter("expression");

得到的expression是Unicode码,不是我们想要的,先变换成ISO8859-1,变换函数如下:

public String toChinese(String ss) {

    //处理中文问题,实现编码转换

    if (ss != null) {

      try {

        String temp_p = ss;

        byte[] temp_t = temp_p.getBytes("ISO8859-1");

        ss = new String(temp_t);

      }

      catch (Exception e) {

        System.err.println("toChinese exception:" + e.getMessage());

        System.err.println("The String is:" + ss);

      }

    }

    return ss;

}

使用expression字符串时通过toChinese处理即可:

if(expression==null)expression="";

        expression=toChinese(expression);  //处理中文问题,实现编码转换。

  这些代码在JavaWebStudio中都是自动完成的,用户只要直接使用就行了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值