JDBC中头文字N类型兼容方法笔记
来源:互联网 发布:spycall软件免费下载 编辑:程序博客网 时间:2024/05/17 05:59
开发JDBC+MS SQL SERVER 相关的内容时,遇到Tomcat 7下UTF-8编码的页面无法正常显示中文文字,而相对地英文字母可以正常显示。如:
Medicine.medBook
ntext:NullableMedicine.
medNameEN
ntext:Nullable0-NNS,gI?0root of Hemsley cowparsnip而真实的数据应该是medBook=《中华本草》 medNameEn=root of Hemsley cowparsnip。
实际页面其字节数为
0-NNS,gI?0/12root of Hemsley cowparsnip/52(即事实上英文字每个前都有类似0x00之类的不可见字符)
根据各种测试,基本得出问题所在:
首先,出现乱码的数据类型为NVARCHAR,使用Unicode编码存储;
我所使用的JDBC尚未实现getNString(int) 方法,这也就意味着在JDBC的读取数据流中,并不能按照nvarchar的方式双字节读取,反而是将一个字拆分为两个单独的字节处理;
SQL SERVER 2008中的编码方式应该是默认的ANSI/GBK。
以上,基本得出上述乱码的来源为N字开头的类型的数据之每一个字都被拆成了2个字节,每个字节在JDBC中转码为JAVA内部使用的Unicode,之后再以对应的字母(基本就是ASCII码)的形式显示出来。
理论上分析的结论是很明显的,可以通过逆转换推出原数据。然而实际上还未成功实现。
相对而言,拿自己之前写过的通用C#SQL查询程序对同一数据库进行连接之后,明显,C#对N字类型的支持要远远好于JAVA,即几乎不需要人工干预,当然这得益于C#的字符类型实现。
//sleep(several_hours);
醒来之后继续研究,这回决定从点到面,先把上述乱码的文字编码全部解析一遍,结果如下:
UnicodeUTF-8GBKCHARraw300Ae3 80 8aa1 b6《0a 304E2De4 b8 add6 d0中2d 4e534Ee5 8d 8ebb aa华4e 53672Ce6 9c acb1 be本2c 678349e8 8d 89b2 dd草48 -125(ffffff83)300Be3 80 8ba1 b7》0b 30就直接观察而言,raw code和Unicode码基本是高低字节位置互换了。于是先尝试将每个接受到的(raw string中的)字符转换为高低字节互换的结果。于是其中涉及到大于0x7f的字节就会有符号问题。这一问题可以通过不直接接收String而是用接受Bytes来改进。附,NetBeans 7+jdk7下的解析结果
run:
《中华本草》
got rei codes(6):300a 4e2d 534e 672c 8349 300b
got raw codes(12):a 30 2d 4e 4e 53 2c 67 49 3f b 30
got uni codes(12):30 a 4e 2d 53 4e 67 2c 3f 49 30 b
《中华本㽉》
Using bytes!
got raw codes(12):a 30 2d 4e 4e 53 2c 67 49 ffffff83 b 30
got uni codes(12):30 a 4e 2d 53 4e 67 2c ffffff83 49 30 b
《中华本草》
成功生成(总时间:1 秒)
包含英文字母的中文内容实例:
public static void main(String[] argv) throws SQLException, UnsupportedEncodingException { ResultSet rs = DBQuery("select medEnvironment from Medicine where medId=58"); boolean hasfirst = rs.first(); System.out.println("Using bytes!"); if (hasfirst) { byte[] bytes = rs.getBytes(1); byte[] nbytes=new byte[bytes.length]; System.out.print("got raw codes(" + bytes.length + "):"); for (byte b : bytes) { System.out.print(Integer.toHexString((int) b) + " "); } System.out.println(); System.out.print("got uni codes("+bytes.length+"):"); for (int i = 0; i < bytes.length; i += 2) { nbytes[i] = bytes[i+1]; nbytes[i + 1] =bytes[i]; System.out.print(Integer.toHexString(nbytes[i]) + " " + Integer.toHexString(nbytes[i + 1]) + " "); } System.out.println(); String newUnicode = new String(nbytes, "Unicode"); System.out.println(newUnicode); } }运行结果为:
run:
Using bytes!
got raw codes(116):1f 75 1 60 ffffffaf 73 ffffff83 58 1a ffffffff 1f 75 ffffff8e 4e 77 6d ffffffd4 62 31 0 30 0 30 0 30 0 6d 0 ffffffe5 4e b 4e ffffff84 76 37 ffffff8c 1 30 53 ffffff90 ffffffef ffffff8d ffffffc1 65 1 30 34 6c ffffff9f 6c ffffffb9 ffffff8f 16 62 ffffff97 67 2d 4e 6e 6f 7f 6e 30 57 2 30 44 ffffff8d ffffff90 6e 6 52 3 5e 1a ffffffff 6 52 3 5e ffffff8e 4e 59 6d 5f 6c 1 30 5f 6c 7f ffffff89 1 30 ffffff8f 79 fffffffa 5e 1 30 56 6e 57 53 1 30 7f 5e 1c 4e 49 7b 30 57 2 30
got uni codes(116):75 1f 60 1 73 ffffffaf 58 ffffff83 ffffffff 1a 75 1f 4e ffffff8e 6d 77 62 ffffffd4 0 31 0 30 0 30 0 30 0 6d 4e ffffffe5 4e b 76 ffffff84 ffffff8c 37 30 1 ffffff90 53 ffffff8d ffffffef 65 ffffffc1 30 1 6c 34 6c ffffff9f ffffff8f ffffffb9 62 16 67 ffffff97 4e 2d 6f 6e 6e 7f 57 30 30 2 ffffff8d 44 6e ffffff90 52 6 5e 3 ffffffff 1a 52 6 5e 3 4e ffffff8e 6d 59 6c 5f 30 1 6c 5f ffffff89 7f 30 1 79 ffffff8f 5e fffffffa 30 1 6e 56 53 57 30 1 5e 7f 4e 1c 7b 49 57 30 30 2
生态环境:生于海拔1000m以下的谷、道路旁、水沟边或林中潮湿地。资源分布:分布于浙江、江西、福建、湖南、广东等地。
成功生成(总时间:1 秒)
- JDBC中头文字N类型兼容方法笔记
- 竖排文字最兼容的方法
- JDBC中结果集类型
- 关于背景透明,文字不透明的最佳方法,兼容IE
- ATX笔记:输入文字方法
- h264流头类型分辨方法
- 错误笔记:JDBC中Statement和PreparedStatement对于Date类型写入数据库问题
- 兼容类型
- 如何修改MSSQL中TEXT类型的长度及用JDBC插入该类型数据的方法
- 在头文件中定义const类型
- JDBC中CLOB字段类型的示例
- jdbc处理Oracle中longrow类型数据
- jdbc处理Oracle中Blob类型数据
- JDBC中Date类型数据的插入
- Java中JDBC获取各种类型数据库连接
- Storm-JDBC 中Date类型转换bug
- JDBC中大文本类型的处理
- JDBC中大文本类型处理
- ACM_3207_HashTable
- ACM_3479_String数组
- ACM_1045_读取float类型,定义double类型
- 循环链表(java实现)
- EBS查询sql scripts
- JDBC中头文字N类型兼容方法笔记
- linux oracle netca命令
- HOWTO: How to Use PeekMessage() Correctly in Windows
- 用 LaTeX 排版编程技术书籍的一些个人经验
- ACM_1240_String和char转换
- OpenCV Mat类矩阵元素访问
- ACM进阶指南
- Tornado - Authentication - tornado.web.authenticated经典写法,带认真
- 找出两个含有相同元素个数的递增数列中第n小的数