一个“”字引发的痛苦经历
(一篇老文章,还有点价值,特意整理了一下。由于涉及客户项目,已经进行了脱敏处理)
1 写在前面的话
虽然这个问题是有解决方案的,但我不建议大家提供给客户,理由见此。
2 问题描述
2010.10.12,业务部门提交问题单(2010.09.14):在对xx铁路局进行“缴费通知单明细信息导入”时,因遇到生僻字“贾”(上龙下天),系统无法识别并报错,使得业务不得不暂停,望给予解决。
3 问题分析
3.1 初步分析
生僻字的乱码问题, 我们认为在生产系统中是不存在的 (除非超出 GBK 字符集的范围),因为系统运行 2 年多来,已经录入了一些不在 GB2312 中的生僻字。
在开发环境中验证,导入存在生僻字的个人基本信息,没有问题;
在 21 测试环境中(AIX+WebLogic+Oracle) ,导入存在生僻字的个人基本信息,有问题,并且在界面上也无法直接录入。
开始在 21 测试环境中分析问题:
1、检查 AIX、ORACLE 等相关字符集设臵,未发现问题;
2、上传文件后,BLOB 字段中的信息正确;
3、修 改 startWeblogic.sh 文 件 , 在 启 动 java 时 , 增 加:
-Dfile.encoding=GBK -Ddefault.client.encoding=GBK,没有效果;
4、修改前台 BAT,增加上述参数,没有效果;
基于第 2 点,证实环境没有问题,怀疑问题出在导入的代码中,可能是读取、转换时造成的乱码。
检查代码。 在 xxx.xx.xxxx.PersonInfoInputBO 类的 batchProcess 方法中, 增加调试输出信息,发现在实际保存数据前,都没有乱码,只是在以下代码执行后,数据库中保存的数据为乱码:
至此,确认代码没有问题,只能怀疑是数据库驱动的问题。使用以下方式验证:
1、删除 WEB-INF/lib/classes12.zip 文件。
2、把 17 上 eprk_a 环境中的数据库连接池驱动类型从 Oracle 改为 Weblogic(数据库:dtp/dtp1521@21_DB)。
重新导入数据,结果正确,未发生乱码现象。
另,在界面上仍无法录入“”字,怀疑与客户端程序(JRE)中的字符集环境设臵有关。
可以确定是 Oracle JDBC 驱动的问题。 Oracle Thin(OJDBC14.jar/Classes12.jar)的 JDBC 驱动与其它数据库的 JDBC 驱动在字符集设臵方面有区别。其它数据库(如DB2/SQLServer 等)的 JDBC 驱动是可以在 URL 中指定字符集的,但 Oracle 的 JDBC 不可以,将自动使用系统、用户的当前字符集。
使用 Weblogic 的数据库驱动,可解决上述问题,并且性能会有所提升,但第三方驱动的安全有效性值得怀疑,且需要大规模测试。
该问题尚未解决。
以上结论有问题。
3.2 进一步分析
部门其他项目组同事打电话说明也存在相同的问题,本人认为这个问题有一定的挑战性,同时需要一个明确的答案,因为以后一定还会碰到,并且这是对本人相对空档时期的严重藐视,故下决心解决此问题。历时一周,在无数次检查、发版、调试、Google、挑灯夜战、希望、失望、绝望。 。 。后,终于有了结论,抱墙痛哭。
之所以形成这个详细的文档,除了记录并缅怀我那近 50个工时外,还希望对我及对本文档感兴趣的同事警示以下基本要点:
一、不要放过任何你认为“应该不会吧”的假设,一定要验证之;
二、必须要有全局视角,对问题的前后左右,每一步进行细致的验证;
三、Microsoft、IBM、ORACLE 都 TM 操蛋!GB 码更操蛋!!
四、不是兄弟我无能,实在是共军太狡猾了。
五、很多事情,你跟他讲理吧,他跟你耍流氓;你跟他耍流氓吧,他跟你讲理。还是耍流氓比较好。唉。
在初步分析中, 结论是 Oracle 数据库驱动的问题, 但在 WINDOWS 中, 使用Oracle JDBC驱动连接相同的数据库是没有问题的,所以这个结论是不正确的,但 Oracle 的驱动的确存在不能设臵字符集的问题。
还是怀疑是环境的问题,在 GBK 和 GB18030 之间反反复复尝试,由于需要在 AIX 上发版,这个过程几乎占用了80%的时间,尝试了几乎所有的可能性和排列组合,问题没有得到解决。
3.2.1 环境检查的要点
1、检查 Oracle 数据库字符集:
select * from nls_database_parameters;
select * from nls_instance_parameters;
select * from nls_session_parameters;
select userenv('language') from dual;
select * from V$NLS_VALID_VALUES v where v.PARAMETER = 'CHARACTERSET';
2、检查 AIX 系统字符集(WINDOWS 系统不用检查)
LANG,应为 GB18030 或 Zh_CN.GB18030(注意大小写)
NLS_LANGUAGE,应为 AMERICAN_AMERICA.ZHS16GBK,经测试,这个参数不设也没有关系,但相关文档中都是这么要求的,所以还是设臵上为好。
在服务器(TOMCAT、Weblogic) 、客户端相应的启动 JAVA 的角本中,增加以下参数:
SUN JDK:-Dfile.encoding=GB18030
IBM JDK:-Dibm.stream.nio=true –Dfile.encoding=GB18030
可以在后台业务处理类或其它地方,嵌入以上代码,并把输出定向到 logger 中,注意输出信息中与encoding 相关的输出值。
BTW:金正日是金日成的儿子。据说翻成 E 文是这样的:The King who is fxxking is the son of the King who has fxxked.
3.2.2 下载 并安装 IBM JDK
IBM JDK 太难下载了。其官网上只提供 JRE 下载,并且必须安装在 IBM 的机器上,会检查BIOS!Fxxk!
IBM_DevelopmentPackage_for_Eclipse_Win32_3.0.0.zip
3.2.3 适配 IBM JDK 和嵌入式 Tomcat
把开发环境中项目的 JRE 改为 IBM JDK 中提供的 JRE,启动 Tomcat,报错:
查了一下,Tomcat 的 SLL 设臵默认使用 SUN 的 X509。但 IBM JDK 中,改成了 IbmX509。
1、在合适的位臵增加 c.setAttribute("algorithm", "IbmX509");
2、注释 main 函数中与 XML 处理相关的代码,如下图:
不知道这样是不是就够了。 我估计不够, 还需要修改 IBM JDK 相关的文件, 具体改了哪里,我不记得了,也不想记得,最终文件如下:
1、把xerces.jar文件放到 ibm_sdk60\jre\lib 目录中;
2、把xerces.properties文件也放到上述目录中。
进行以上修正后,StartServer 能够在 IBM JDK 中正常使用。
3.3 问题解决
3.3.1 查看数据库 BLOB 字段中的内容
前文描述过,上传文件后,数据库中 BLOB 字段中的数据看起来没有问题。
所以从来没有怀疑在导入操作前就存在问题,到这个地步,只能再往前走,根据目前掌握的信息,怀疑在上传时,就存在问题了,理由如下:
1、在跟踪“导入”代码时,发现虽然这个字能够输出到日志,但其 value 值为空;
2、GB18030 针对 GBK 增补的汉字(特别是 FE 区),在 Unicode 中有两个编码;
3.3.2 在ORACLE 中进行编码转换试验
说明:Convert(内容,目标字符集,来源字符集)
特别注意 GBK2GB18030,乱码了。GBK 是 GB18030 的子集,它们之间的转码根据官方描述应不存在问题,但实际转码时“屁”没有问题, “”有问题。个人推断:Oracle 内部默认字符为Unicode(UTF8), 在进行转码时, 使用Unicode 编码方式进行中间过渡, 导致在Unicode中有两个编码、GB18030 中只有一个编码的汉字乱码。
查看源文件中的编码:
也没有问题啊!唉,这里看起来是没有问题,而且 16 进制编码与数据库 BLOB 字段的也一样,但问题的关键却就在这里。我试着说一下我的理解,不一定对哈:
3.3.3 修改源文件编码格式
使用 EditPlus 打开 txt 文件, “另存为” :
注意:默认情况下, “编码”框中没有 GB18030,需要先使用“More…”引入,方式为在弹出框中把需要的编码放到左边就行:
xxx.xx.xxxx.mapping.DataMapping
增加红色部分的代码。
修改红色部分代码。
xxx.xx.xxxx.File_upBO
修改红色部分代码。
3.3.4 修改 JRE 参数
为 StartServer、LoginUI 指定正确的 JRE 参数:
注意:如果使用 Client,必须在 login.bat 中进行相应的设置。
3.3.5 运行并测试
4 要点总结
5、 操作系统用户的语言环境必须是 GB18030,包括数据库 NLS 设臵;
6、 数据库编码必须为 ZHS16GBK。(如果是 ZHS32GB18030 呢?没有环境测试,想来也是正确的)
7、 以本例来看,由于来源数据是 txt 类型的,所以对应到 BLOB 字段是不合适的,如果使用 CLOB,情况要简单得多,代码也要简单得多。
5 体会
1、 汉字的标准化、国际化,还有很长的路要走啊,并且很可能现在就走乱啦,不知道几只脚在走路啦。
6 最终结论及建议
先发点牢骚,你说 GB2312 中 6 千多个汉字不够起名用的,那么兄台,GBK 中 2.1 万个汉字可够?你一定要 GB18030 吗?为什么?WINDOWS都不支持呀,很多输入法都不支持呀,身份证、银行卡等一系列需要把信息保存到计算机的事你很可能都没法办了呀。一定要?俺给你起个名,SB!
按照我前一个行业的经验来看,名字实在不宜起得太复杂。最好就用 GB2312 里的字,太复杂了的话,要么连老师都不认识,要么写起来麻烦。你想想,人家孩子的名字 10 来个笔划,你家孩子的名字 100 来个笔划,新学期发下 10 来本练习本,要求立刻把姓名都写上,你信不信你家孩子写哭了也写不好?造孽呀。
言归正传,虽然这个问题是有解决方案的,但我不建议大家提供给客户,理由如下:
1、 Windows默认编码为 GBK,很多输入法也是;
2、 就算解决了这个生僻字,不知道还没有其它生僻字有问题?康熙字典中有 4.7 万个汉字,能全部支持吗?不能!
3、 你架不住有强人如武则天,在仓颉、许慎等人基础上,自己造字吧?
4、 在计算机里,存在太多的方言,也有太多的水翻译,并且有些方言里的字,在其它方言里根本不存在——讲理的话,应该、必须存在的。
5、 要大范围检查并修改代码。
6、 测试覆盖率怎么定?生僻字怎么定义?我们知道有多少生僻字么?
结论:对于 GBK 没有收录的汉字,系统也不提供支持。要么拆开输入,要么用拼音代替,要么客户自己想替代方案。
对于怎么判断汉字在不在 GBK 里,目前我能想到的比较省事但客户操作起来比较麻烦的解决方案是这样的: 我们向客户提供附件中的 GBK 汉字编码表, 由客户在需要时去一一对比。
不知道客户会不会接收?或自动放弃?或自动想其它办法?
我的方法或描述可能存在问题,但我的结论就这样了。爱咋地咋地。
7 附
7.1 汉字编码表
GBK汉字编码对照表.xls
gb18030的汉字编码.xls
7.2 GB18030 针对 GBK 增补的部分汉字(FE 区 )
增补汉字和部首 80 个, 包括 28 个部首和 52 个汉字。 GBK 编码是从 FE50-FE7E, FE80-FEA0。
转载于:https://www.cnblogs.com/yujj-cn/p/4915838.html
一个“”字引发的痛苦经历相关推荐
- 一个EXE引发的危机 — 浏览器劫持实战篇
一个EXE引发的危机 --浏览器劫持实战篇 作者:小金 转载请注明出处和作者 一. 一个EXE引发的危机 网络程序员小李最近有点忙,公司要做的网页工程项目已经快到尾期了,可是开发小组的进度仍然迟迟跟不 ...
- 江民在线杀毒充值的痛苦经历
江民公司在我这次痛苦经历之前给我的感觉都是很好的,作为一个民族企业,我一直都很支持,是发自内心深处的,可是又如何呢? 我已经是他们公司的杀毒2006下载版的正式用户,现在我想在此基础上再增加一项&qu ...
- 一个高中生的编程自学经历
年轻时的linus 最近,在看雪论坛上看到了一个高中生分享的自学经历,想起我第一次学习编程时候,当年高考后,由于大学选了计算机专业,就好奇去了看一本c语言编程(书是亲戚的)书籍,好奇心驱使我们主动去探 ...
- 一个馒头引发血案,服务在“峰终定律”中的最大变数是什么
这是小胖的第140篇文章. 也是小胖2020年100文章的第15篇. 「创业难, 守业更难.」 本文2920字,阅读大概需要5分钟. 作者:小胖 编辑:小胖 最近的购物体验好坏参半,所以不妨来讲一讲用 ...
- 菜鸟找帝国时代全局基址的痛苦经历
前言:三年前,我就一直在找这个游戏的基址,大约一年前,找到过一次,并成功的写出了修改资源的辅助工具,但游戏中的人口上限问题一直没能解决,四处发贴求助,广海也发过.hehe 最近用OD找到了人口 ...
- vue 循环 递归组件_Vue一个案例引发的递归组件的使用
今天我们继续使用 Vue 的撸我们的实战项目,只有在实战中我们才会领悟更多,光纸上谈兵然并卵,继上篇我们的<Vue一个案例引发的动态组件与全局事件绑定总结> 之后,今天来聊一聊我们如何在项 ...
- Spring之LoadTimeWeaver——一个需求引发的思考---转
原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver--一个需求引 ...
- 『转』度百死去飞秋一个BUG引发的血案
作了一篇文章度百死去飞秋一个BUG引发的血案,昨天,度百死去的美国客户发邮件给我,说我的软件出问题了,我查来查去,发现居然是服务器上一个目录无法删除,一删除就报 cannot read from th ...
- 【Elasticsearch】es 一个数据精度引发的血案
1.概述 在看博客的时候,发现有个博客 一个数据精度引发的血案 上面说,数据精度会丢失,然后我在 7.8.0版本的es测试,发现数据没有丢失. POST /index-lcc-0002/_doc {& ...
最新文章
- vue使用命令行构建完项目后_vue-cli 构建项目在IE中无法运行解决方式(build之后可运行)...
- 袖口里的“超能力”:Facebook腕带式AR传感器,可隔空打字、操控界面,LeCun点赞...
- apt-get出现no public key available for the following key IDs
- python电脑配置大概要多少钱-学python最电脑配置有要求么
- unity中单位是米还是厘米_【一步数学】小学数学单位换算公式大全及专项训练...
- linux网络编程之TCP三次握手和四次挥手
- Android开发笔记(六十六)自定义对话框
- HDOJ 4734 数位DP
- Num37 spring 事务 ssh整合
- 楼道声光控灯闪烁_照明灯闪烁其中一个原因就是它
- Java代码优化的一些方法(总结)
- WinForm界面开发教程:DevExpress WidgetView使用介绍
- 修改博图组态原有GSD文件
- linux 代码编辑器软件下载,Visual Studio Code下载
- 实验二 任务二 体重测量
- 【Java设计模式】责任链模式
- CF 339C Xenia and Weights 背包
- Deep Pyramidal Residual Networks for Spectral-Spatial HSIs Classification(2019)——深度学习论文笔记(二)
- 传统家装有落差,VR全景家装让你体验新房落成效果
- 怪诞行为学 读书笔记