- 浏览: 983918 次
文章分类
- 全部博客 (428)
- Hadoop (2)
- HBase (1)
- ELK (1)
- ActiveMQ (13)
- Kafka (5)
- Redis (14)
- Dubbo (1)
- Memcached (5)
- Netty (56)
- Mina (34)
- NIO (51)
- JUC (53)
- Spring (13)
- Mybatis (17)
- MySQL (21)
- JDBC (12)
- C3P0 (5)
- Tomcat (13)
- SLF4J-log4j (9)
- P6Spy (4)
- Quartz (12)
- Zabbix (7)
- JAVA (9)
- Linux (15)
- HTML (9)
- Lucene (0)
- JS (2)
- WebService (1)
- Maven (4)
- Oracle&MSSQL (14)
- iText (11)
- Development Tools (8)
- UTILS (4)
- LIFE (8)
最新评论
-
Donald_Draper:
Donald_Draper 写道刘落落cici 写道能给我发一 ...
DatagramChannelImpl 解析三(多播) -
Donald_Draper:
刘落落cici 写道能给我发一份这个类的源码吗Datagram ...
DatagramChannelImpl 解析三(多播) -
lyfyouyun:
请问楼主,执行消息发送的时候,报错:Transport sch ...
ActiveMQ连接工厂、连接详解 -
ezlhq:
关于 PollArrayWrapper 状态含义猜测:参考 S ...
WindowsSelectorImpl解析一(FdMap,PollArrayWrapper) -
flyfeifei66:
打算使用xmemcache作为memcache的客户端,由于x ...
Memcached分布式客户端(Xmemcached)
用jdcb查询SQL Server数据源数据时,在window环境下数据没有任何异常,但到linux环境下,英文和数字没有任何问题,但中文出现乱码,搜索SQLServer jdbc乱码原因,没有得到想要的答案,于是,从SQLServer驱动的实现开始,查找没有想Mysql配置url是,编码属性配置:
//SQLServerDriver
先来看解析url:
//Util
没有找到字符编码相关的属性配置
再来看获取连接:
//SQLServerConnection
仍然没有找到对应的字符编码相关属性:
那会是什么原因呢?
一想,在Mysql jdbc相关的文章中我们看到Mysql jdbc连接与客户端时通过socket的连接来通信的,那么MS SqlServer思想肯定也是一样,那么socket的接收byte数据要转化为String,那肯定要使用
如下方法:
//String
如果没有配置编码,则使用如方法:
//StringCoding
猜想是不是系统编码导致的呢?linux系统的编码为UTF-8
修改系统编码为GBK,修改/etc/profile,添加如下两行:
重新启动应用,测试,it is ok, feel good...
如果不是这个原因可以尝试从结果结果集中先获取数据,再将数据转换为GBK编码格式:
这种方法理论上没有任何问题,我没有测试,如果上面方法不行,可以尝试用这种方法。
//SQLServerDriver
public Connection connect(String s, Properties properties) throws SQLServerException { try { Logger.setLogWriter(this, DriverManager.getLogWriter()); } catch(NoSuchMethodError nosuchmethoderror) { Util.println("This version of sqlserver jdbc driver needs the JVM to support level 1.4 or higher"); Util.println("The current JVM level is:" + Util.sJDKVersion); try { Logger.setLogStream(this, DriverManager.getLogStream()); } catch(Exception exception) { } } SQLServerConnection sqlserverconnection = null; //解析URL Properties properties1 = Util.parseUrl(s); if(properties1 == null) return null; Object obj = null; Object obj1 = null; int i = DriverManager.getLoginTimeout(); if(i > 0) properties1.put("loginTimeout", (new Integer(i)).toString()); for(int j = 0; j < driverProperties.length; j++) { String s1 = driverProperties[j]; if(properties1.getProperty(s1) != null) continue; String s2 = properties.getProperty(s1); if(s2 != null) properties1.put(s1, s2); } connProperties = properties1; String s3 = properties1.getProperty("logfile"); if(s3 != null) Logger.setCustomLogFile(this, s3); sqlserverconnection = new SQLServerConnection(); sqlserverconnection.sConnectURL = s; try { //获取连接 sqlserverconnection.connect(properties1, null); } catch(SQLException sqlexception) { throw new SQLServerException(sqlserverconnection, "Failed Logon:" + sqlexception.toString() + " url:" + s, sqlexception.getSQLState(), sqlexception.getErrorCode(), false); } return sqlserverconnection; }
先来看解析url:
Properties properties1 = Util.parseUrl(s);
//Util
public static Properties parseUrl(String s) { Properties properties = new Properties(); String s1 = s; Object obj = null; Object obj1 = null; String s3 = "jdbc:sqlserver://"; if(!s1.startsWith(s3)) return null; s1 = s1.substring(s3.length()); try { StringTokenizer stringtokenizer = new StringTokenizer(s1, ":/&?;", true); String s2 = stringtokenizer.nextToken(); properties.put("serverName", s2); String s4 = stringtokenizer.nextToken(); if(s4.equals(":")) { String s7 = stringtokenizer.nextToken(); properties.put("portNumber", s7); String s5 = stringtokenizer.nextToken(); } int i = 0; do { if(!stringtokenizer.hasMoreTokens()) break; String s6 = stringtokenizer.nextToken(); if(++i % 2 != 0) { StringTokenizer stringtokenizer1 = new StringTokenizer(s6, "=", true); String s8 = stringtokenizer1.nextToken(); if(stringtokenizer1.hasMoreTokens()) { stringtokenizer1.nextToken(); if(stringtokenizer1.hasMoreTokens()) { String s9 = stringtokenizer1.nextToken(); properties.put(s8, s9); } } else { properties.put("databaseName", s8); } } } while(true); } catch(NoSuchElementException nosuchelementexception) { } return properties; }
没有找到字符编码相关的属性配置
再来看获取连接:
//SQLServerConnection
public Connection connect(Properties properties, BasePooledConnection basepooledconnection) throws SQLServerException { int k; ConnectionProperties connectionproperties; int l; int i1; int i2; activeConnectionProperties = properties; pooledConnectionParent = basepooledconnection; conPropertiesArray = new ConnectionProperties[10]; for(int i = 0; i < 10; i++) conPropertiesArray[i] = new ConnectionProperties(); String s = null; String s1 = null; //获取数据库连接属性配置 s = properties.getProperty("enableFailover"); boolean flag = s != null && s.equals("true"); s = "user"; s1 = properties.getProperty(s); if(s1 == null) s1 = ""; buildConnectionProperties(s, s1, flag); s = "password"; s1 = properties.getProperty(s); if(s1 == null) s1 = ""; buildConnectionProperties(s, s1, flag); s = "databaseName"; s1 = properties.getProperty(s); if(s1 == null) s1 = properties.getProperty("database"); buildConnectionProperties(s, s1, flag); String s2 = s1; s = "serverName"; s1 = properties.getProperty(s); if(s1 == null) s1 = properties.getProperty("host"); if(s1 == null) s1 = "localhost"; String s3 = s1; int j = s1.indexOf('\\'); String s4 = null; if(j >= 0) { String s5 = s1.substring(j + 1, s1.length()); s1 = s1.substring(0, j); s4 = getInstancePort(s1, s5); } else { String s6 = properties.getProperty("instanceName"); if(s6 != null) s4 = getInstancePort(s1, s6); } buildConnectionProperties(s, s1, flag); s = "portNumber"; s1 = properties.getProperty(s); if(s1 == null) s1 = properties.getProperty("port"); if(s1 == null || s1.equals("0")) if(s4 == null) s1 = "1433"; else s1 = s4; buildConnectionProperties(s, s1, flag); s = "sqlVersion"; s1 = properties.getProperty(s); if(s1 == null) s1 = properties.getProperty("sqlversion"); buildConnectionProperties(s, s1, flag); s = "asciiStringParameters"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "booleanLiterals"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "applicationName"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "instanceName"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "lastUpdateCount"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "disableStatementPooling"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "trustedAuthentication"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "codepage"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "loginTimeout"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "lockTimeout"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "xopenStates"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "enableFailover"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "selectMethod"; s1 = properties.getProperty(s); if(s1 == null || !s1.equals("cursor")) s1 = "default"; buildConnectionProperties(s, s1, flag); s = "preExecuteMetaData"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "iterativeBatching"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "connectionRetryCount"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "connectionRetryWait"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "trustedAuthenticationPort"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "ntlmAuthentication"; s1 = properties.getProperty(s); buildConnectionProperties(s, s1, flag); s = "domain"; s1 = properties.getProperty(s); ... }
仍然没有找到对应的字符编码相关属性:
那会是什么原因呢?
一想,在Mysql jdbc相关的文章中我们看到Mysql jdbc连接与客户端时通过socket的连接来通信的,那么MS SqlServer思想肯定也是一样,那么socket的接收byte数据要转化为String,那肯定要使用
如下方法:
//String
public String(byte bytes[], Charset charset) { this(bytes, 0, bytes.length, charset); }
如果没有配置编码,则使用如方法:
public String(byte bytes[]) { this(bytes, 0, bytes.length); }
public String(byte bytes[], int offset, int length) { checkBounds(bytes, offset, length); //委托给StringCoding解码 this.value = StringCoding.decode(bytes, offset, length); }
//StringCoding
static char[] decode(byte[] ba, int off, int len) { //关键在这句获取系统默认字符编码 String csn = Charset.defaultCharset().name(); try { // use charset name decode() variant which provides caching. return decode(csn, ba, off, len); } catch (UnsupportedEncodingException x) { warnUnsupportedCharset(csn); } try { return decode("ISO-8859-1", ba, off, len); } catch (UnsupportedEncodingException x) { // If this code is hit during VM initialization, MessageUtils is // the only way we will be able to get any kind of error message. MessageUtils.err("ISO-8859-1 charset not available: " + x.toString()); // If we can not find ISO-8859-1 (a required encoding) then things // are seriously wrong with the installation. System.exit(1); return null; } } public static Charset defaultCharset() { if (defaultCharset == null) { synchronized (Charset.class) { //在当前线程访问控制权限下,获取系统文件编码 String csn = AccessController.doPrivileged( new GetPropertyAction("file.encoding")); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; else //如果系统编码为空,则默认为UTF-8 defaultCharset = forName("UTF-8"); } } return defaultCharset; }
猜想是不是系统编码导致的呢?linux系统的编码为UTF-8
donald@linux:~/tomcat/bin>locale ... LC_ALL=zh_CN.UTF-8 LANG=zh_CN.UTF-8
修改系统编码为GBK,修改/etc/profile,添加如下两行:
export LC_ALL=zh_CN.G export LANG=zh_CN.GBK
donald@linux:~/tomcat/bin>source /etc/profile donald@linux:~/tomcat/bin> tail -n 20 /etc/profile ... export LC_ALL=zh_CN.GBK export LANG=zh_CN.GBK donald@linux:~/tomcat/bin>
重新启动应用,测试,it is ok, feel good...
如果不是这个原因可以尝试从结果结果集中先获取数据,再将数据转换为GBK编码格式:
String oname=rs.getString("name"); byte[] namebyte=oname.getBytes("GBK2312"); name=new String(namebyte);
这种方法理论上没有任何问题,我没有测试,如果上面方法不行,可以尝试用这种方法。
发表评论
-
修改Oracle最大连接数和会话数
2017-05-04 11:49 4746ORACLE 最大连接数的问题 ... -
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP解决办法
2017-05-04 11:27 7355解决ora-01652无法通过128(在temp表空间中)扩展 ... -
SQL Server大表数据的导出与导入命令BCP
2017-04-24 23:07 3573SQLServer备份还原命令Sqlcmd,osql,iSql ... -
Oracle性能查看
2017-02-24 15:57 985Oracle数据库在配置文件中更改最大连接数:http://w ... -
oracle字段类型转换的处理
2016-11-04 21:49 1109Oracle的CLOB类型数据处理:http://donald ... -
Oracle的CLOB类型数据处理
2016-11-04 11:32 1329Oracle菜鸟之grant授权:http://www.2ct ... -
Oracle客户端SQLPLUS教程
2016-10-31 19:00 1940Oracle 角色及权限:http://blog.csdn.n ... -
oracle占比函数ratio_to_report
2016-08-26 11:06 1483参考:http://blog.csdn.net/ningjie ... -
Oracle over函数
2016-08-25 17:52 615oracle over函数简介:http: ... -
oracle分组
2016-08-23 13:52 600Group by 函数往往不能把多个不同分组分为一个组,这是我 ... -
Oracle 分页
2016-08-23 12:31 508详解Oracle的几种分页查询语句:http://databa ... -
Oracle的Select Case用法
2016-08-16 18:10 1803#保留两位小数: round((ny.AMOUNT-oy.AM ... -
java连接Oracle
2016-07-08 18:27 1117import java.sql.Connection; im ...
相关推荐
"Java-JDCB.zip"这个压缩包包含了一系列与Java相关的教程,主要聚焦于Java Servlet、JDBC和JSP(JavaServer Pages)这三大核心概念,是学习Java后端开发的重要资源。 首先,我们来看"Java_Servlet入门教程"。...
JDBC提供了统一的接口,让开发者无需关心底层数据库的细节,就能进行SQL查询和数据操作。使用JDBC的流程通常包括加载驱动、建立连接、创建Statement或PreparedStatement对象、执行SQL语句、处理结果集以及关闭资源。...
很好用的JDBC
"yuanshen.sql"和"_yuanshen.sql"是数据库的备份文件,可能包含了预设的表结构和测试数据。"YuanShen"可能是一个包含其他项目文件或资源的文件夹。 总结,"原神官网"项目展示了现代Web开发的全栈流程,从前端的UI...
Sap HaNa 数据库链接 jar包。可自定义Maven坐标 添加到私有库 想不要积分,CSDN 最低要求1积分 #mvn install:install-file -Dfile=C:\work\hanajdbclib\ngdbc.jar -DgroupId=sap.hana.jdbc -DartifactId=ngdbc -...
jdbc的工具类,平时用的很顺手,今天共享出来给大伙,有需要的下下
是一个简单的,基于Netty,异步,高性能和可靠的数据库驱动程序,用于用Kotlin编写的PostgreSQL和MySQL。 入门 // Connection to MySQL DB Connection connection = MySQLConnectionBuilder ....
`dbtest.sql`可能是用于测试数据库的SQL脚本,可能包括创建表、插入数据等操作,以便于开发者验证连接池和JdbcTemplate的配置是否正确。 总的来说,Java数据库连接池如C3P0和Druid,以及Spring的JdbcTemplate,都是...
这是我刚开始学JDCB 时的工程(刚整理出来)---Version1.0 : 表说明: 表名 customer 列名 cid ,cname, cpassword 工程说明:对单表的 增 删 改 查 。...
这个项目前端采用HTML+CSS+JS实现,后端采用JDCB+Servlet+JSP实现,后端实现了CRUD的操作,前端页面风格统一、美观,可以切换多种风格,现代风、古风等等,正在做毕业设计的小伙伴们或者有需要的小伙伴都可以下载...