网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.0. Preface: Core Technologies.
.WebWork 2.1.1发布.
.一步一步教你如何在linux下配置a.
.TOMCAT+JIVE的安装配置(支持中文).
.Javascript实例教程(20) OLE Aut.
.类的实例创建.
.深入讨论JAVA字节码加密技术(1).
.Java的秘密:使用全屏幕模式.
.Java学习之深入研究类的各种属性.
.JAVA学习笔记swingJFrame窗口学习.
.Java类体中的this和super的用法.
.用Java实现网络语音信号传送.
.体验Java 1.5中面向方面(AOP)编程.
.深入讨论JAVA字节码加密技术(2).
.Java 开发环境的过去、现在和将来.
.用JAVA将大图片文件转换出小的缩.
.使用Socket通道读取web页面.
.关于Java语言开发编程中JDBC的介.
.java自己做个每小时自动更新的代.
.Java中运行其它程序方法的实例详.

Java数据库字符国际化

发表日期:2008-1-5



  数据库字符国际化是大家提问最多的问题,例如mysql数据库大家可能在JDBC-URL添加useUnicode=true&CharacterEncoding=GBK作为中文支持的基本条件。但这有时破坏了数据的完整性,假如某些人粗心大意,就会导致数据编码错误,产生乱码。因此,我们需要一些手段在程序内部进行编码处理。人们一般通过在应用上使用 String(bytes:byte[], enc:String)/String.getBytes(enc:String)进行字符串编解码,这样做虽然易懂,但是假如碰到大字段表格,手动编码时费时费力。
  
  我的方法:通过研究JDK类库,可以感觉到多层处理机制在数据处理上的优越性。我们完全有可能在数据库上建立一个中间层用于字符的国际化处理,我就是这么做的。仔细研究一下JDBC操作数据库出现字符编码问题的根源,很轻易发现多数情况是ResultSet的几个String方法在作怪,因此我们就完全可以编写一个ResultSet中间层进行国际化处理,源码如下:
  
  public class I18nResultSet implements ResultSet{ private String encoding; private ResultSet rs; public I18nResultSet(ResultSet rs, String encoding) throws Java.io.UnsupportedEncodingException{ //检查该编码名称是否被系统支持。 "".getBytes(encoding); this.rs = rs; this.encoding = encoding; } … … //以下几个方法是进行String字符串的重编码. public String getString(int index) throws SQLException{ String data = null; try{ data = new String(rs.getBytes(index), encoding); }catch(java.io.UnsupportedEncodingException uee){} } public String getString(Stirng field) throws SQLException{ String data = null; try{ data = new String(rs.getBytes(field), encoding); }catch(java.io.UnsupportedEncodingException uee){} } public void updateString(int index, String value) throws SQLException{ try{ rs.updateBytes(index, value.getBytes(encoding)); }catch(java.io.UnsupportedEncodingException uee){} } public void updateString(String field, String value) throws SQLException{ try{ rs.updateBytes(field, value.getBytes(encoding)); }catch(java.io.UnsupportedEncodingException uee){} } … …}
  
  
  可以看出, 所有的String操作都使用特定编码的字节数组进行存取,这样通过定义encoding的值实现数据库存取数据编码的一致性,且encoding完全可以通过在配置信息中动态定义。
  
  同时,上面的程序又可以解决一些固有的字符串处理问题,例如控制符如\r\n导入到数据库中很有可能被解析为\\r\\n使其不能换行,通过字节数组操作,就可以解决这个问题。这样像文章固有格式就可以完整地保留下来而不需要进行额外转换操作。
  
  结论,通过多层处理机制使用中间层对数据库数据进行层层处理可使处理环节之间形成松耦合关系,从而可以进行有效的控制。
  
  下面给一个使用动态代理进行字符控制的代码(原创):
  
  package com.yipsilon.crocodile.database;import java.sql.ResultSet;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.io.UnsupportedEncodingException;/** * 作者 yipsilon * 如要转载, 请通知作者 */public class I18nResultSetHandler implements InvocationHandler{ private ResultSet rs; private String encoding; public I18nResultSetHandler(ResultSet rs, String encoding) throws UnsupportedEncodingException{ this.rs = rs; "".getBytes(encoding); this.encoding = encoding; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ String methodName = method.getName(); if(methodName.equals("getString")){ Object obj = args[0]; if(obj instanceof Integer){ return decodeString(rs.getBytes(((Integer)obj).intValue()), encoding); }else{ return decodeString(rs.getBytes((String)obj), encoding); } }else if(methodName.equals("updateString")){ Object obj = args[0]; if(obj instanceof Integer){ rs.updateBytes(((Integer)obj).intValue(), encodeString((String)args[1], encoding)); }else{ rs.updateBytes((String)obj, encodeString((String)args[1], encoding)); } return null; } return method.invoke(rs, args); } private String decodeString(byte[] bytes, String enc){ try{ return new String(bytes, enc); } catch(UnsupportedEncodingException uee){ return new String(bytes); } } private byte[] encodeString(String str, String enc){ try{ return str.getBytes(enc); } catch(UnsupportedEncodingException uee){ return str.getBytes(); } }}
  
  
  使用时调用:
  
  ResultSet rs = ... ; //原始的ResultSet结果集String encoding = "GBK"; //字符编码(ResultSet)Proxy.newProxyInstance(rs.getClass().getClassLoader(), rs.getClass().getInterfaces(), new I18nResultSetHandler(rs, encoding));
上一篇:创建接口 人气:568
下一篇:什么是面向对象的设计思想? 人气:1116
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐