//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; // Parse the 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 { // get connection sqlserverconnection.connect(properties1, null); } catch(SQLException sqlexception) { throw new SQLServerException(sqlserverconnection, "Failed Logon:" + sqlexception.toString() + " url:" + s, sqlexception.getSQLState(), sqlexception.getErrorCode(), false); } return sqlserverconnection; }
Let's first look at parsing the url:
Properties properties1 = Util.parseUrl(s);
//Useful
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; }
The property configuration related
to Let's look at getting the connection:
//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; //Get database connection property configuration 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); ... }
Still haven't found the corresponding character encoding related property:
what could be the reason?
When I think about it, in the articles related to Mysql jdbc, we see that Mysql jdbc communicates with the client through the socket connection, so the idea of MS SqlServer must be the same, then the received byte data of the socket must be converted into String, it must be Use the
following method:
//String
public String(byte bytes[], Charset charset) { this(bytes, 0, bytes.length, charset); }
If no encoding is configured, use such as:
public String(byte bytes[]) { this(bytes, 0, bytes.length); }
public String(byte bytes[], int offset, int length) { checkBounds(bytes, offset, length); / / Delegate to StringCoding decoding this.value = StringCoding.decode(bytes, offset, length); }
//StringCoding
static char[] decode(byte[] ba, int off, int len) { //The key is to get the system default character encoding in this sentence 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) { //Under the access control permission of the current thread, get the system file code String csn = AccessController.doPrivileged( new GetPropertyAction("file.encoding")); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; else //If the system encoding is empty, the default is UTF-8 defaultCharset = forName("UTF-8"); } } return defaultCharset; }
Guess it is caused by system coding? The encoding of the linux system is UTF-8
donald@linux:~/tomcat/bin>locale ... LC_ALL=zh_CN.UTF-8 LANG = zh_CN.UTF-8
Modify the system code to GBK, modify /etc/profile, and add the following two lines:
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>
Restart the application, test, it is ok, feel good...
If this is not the case, you can try to get the data from the result set first, and then convert the data to GBK encoding format:
String oname=rs.getString("name"); byte[] namebyte=oname.getBytes("GBK2312"); name=new String(namebyte);
There is no problem with this method in theory. I have not tested it. If the above method does not work, you can try this method.