久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Java常見(jiàn)亂碼原理及解決方案

 ahthzxs 2015-10-26

String odsStr = "測(cè)試";

String newStr = new String(odsStr.getBytes("GBK"), "ISO8859_1");

首先需要說(shuō)明一下我們經(jīng)常用到的字符集,,有ISO8859-1,,GB2312,GBK,,GB18030,,UNICODE。這里ISO8859-1字符集只 包含英文字符,,使用一個(gè)字節(jié)存儲(chǔ),。GB2312、GBK和GB18030字符集包含中文字符,,他們都兼容ISO8859-1字符集,,他們的字符存儲(chǔ)格式是變長(zhǎng)的,其中GB18030包含GBK,,GBK包含GB2312,。UNICODE包含世界上所有國(guó)家的字符,UNICODE又分為UTF-8,,UTF-16和UTF-32三種,,UTF-8是變長(zhǎng)字符集,,它兼容ISO8859-1,即英文字符使用一個(gè)字節(jié)編碼,,而其他的字符使用2到4個(gè)字節(jié)編碼,,其中中文字符大部分都是使用3個(gè)字節(jié)進(jìn)行編碼,少量偏僻字使用4個(gè)字節(jié)編碼,,UTF-16統(tǒng)一都使用2個(gè)字節(jié)編碼,,它不兼容ISO8859-1,英文字符也使用兩個(gè)字節(jié),,UTF-32統(tǒng)一使用4個(gè)字節(jié)編碼,,也不兼容ISO8859-1,可見(jiàn)UTF-16和UTF-32都比較浪費(fèi)空間,。

亂碼問(wèn)題的產(chǎn)生最根本的原因就是使用錯(cuò)誤的字符集解碼字節(jié)流或者將給定的字符串用錯(cuò)誤的字符集編碼成錯(cuò)誤字節(jié)流造成的,,例如”中文”兩個(gè)漢字,如果用ISO8859-1字符集將其編碼為字節(jié)流,,因?yàn)檫@個(gè)字符集不支持中文,,所以就會(huì)出錯(cuò),輸出結(jié)果為3f3f,,其意義就是??,。再例如”中文”二字的GBK的字節(jié)流為d6 d0 ce c4,可是我們要是用不兼容的字符集去解碼,,例如用ISO8859-1或者UTF-8,,這隨后產(chǎn)生的字符串就是亂碼,或者是其他的某個(gè)字符,。

從開(kāi)發(fā)Java程序到運(yùn)行Java程序的過(guò)程中都存在著編碼問(wèn)題,,所以要想避免亂碼產(chǎn)生,就必須了解在其中任何時(shí)候的編碼處理的情況,。

源代碼:在編寫java源代碼的時(shí)候,,我們必須把編寫的文本保存在文件中,這個(gè)時(shí)候不管用什么編輯器,,都存在一個(gè)問(wèn)題,,就是以什么樣的字符集將這些源代碼(包含漢字)保存到文件中,大部分編輯器都會(huì)通過(guò)系統(tǒng)的環(huán)境變量得到系統(tǒng)的當(dāng)前默認(rèn)字符集,,編輯器就會(huì)使用這個(gè)字符集將我們編寫的源代碼保存到文件中,。一般我們的中文Windows系統(tǒng)的默認(rèn)字符集是GB18030,,AIX英文環(huán)境的默認(rèn)字符集是ISO8859-1,,AIX中文環(huán)境的默認(rèn)字符集是IBM-eucCN,。

編譯:在編譯.java文件的時(shí)候如果使用默認(rèn)處理,,則javac會(huì)使用系統(tǒng)當(dāng)前的默認(rèn)字符集去讀取源文件,將源文件的內(nèi)容轉(zhuǎn)換為UTF-8編碼,,然后在進(jìn)行編譯,,這時(shí)我們也可以通過(guò)-encoding參數(shù)指定一個(gè)字符集,,讓javac使用我們指定的字符集去讀取源代碼然后在轉(zhuǎn)換為UTF-8,然后編譯,。編譯以后產(chǎn)生的class文件內(nèi)部所有的中文字符都是用UTF-8的字符集進(jìn)行編碼的,,這就是Java程序能處理任何國(guó)家文字的原因。

運(yùn)行時(shí):Java程序在運(yùn)行時(shí),,需要使用程序內(nèi)部定義的中文字符串,,也可能會(huì)使用從外部讀取的中文字符串,這些經(jīng)過(guò)處理,,可能都會(huì)輸出到程序外部,,在這些 過(guò)程中都涉及到編碼的轉(zhuǎn)換,程序內(nèi)部定義的字符串都是用UTF-8存儲(chǔ)的,。而從外部讀取和輸出到程序外部的輸出又使用什么字符集進(jìn)行處理呢?在我們沒(méi)有在 程序中特別指定的情況下,,JVM會(huì)根據(jù)系統(tǒng)屬性確定使用哪個(gè)字符集,,這個(gè)系統(tǒng)屬性的名稱為file.encoding,我們可以在啟動(dòng)java程序的時(shí)候通過(guò)-D參數(shù)設(shè)定這個(gè)值,,如果沒(méi)有設(shè)定,,JVM會(huì)根據(jù)系統(tǒng)環(huán)境變量確定這個(gè)系統(tǒng)屬性,一般我們的中文Windows系統(tǒng)的默認(rèn)字符集是GB18030,,AIX英文環(huán)境的默認(rèn)字符集是ISO8859-1,,AIX中文環(huán)境的默認(rèn)字符集是IBM-eucCN。這樣JVM在處理輸入數(shù)據(jù)的時(shí)候就會(huì)把字節(jié)流根據(jù)這個(gè)參數(shù)進(jìn)行解碼,,然后轉(zhuǎn)成UTF-8格式,,在Java程序內(nèi)部處理,然后再根據(jù)這個(gè)參數(shù)把處理后的數(shù)據(jù)編碼,,輸出到程序外部,。這就是Java程序運(yùn)行時(shí)字符集的使用情況。

現(xiàn)在有一個(gè)問(wèn)題,,我們平時(shí)都是Windows的中文環(huán)境下做開(kāi)發(fā),,然后拿到AIX系統(tǒng)上去運(yùn)行,AIX系統(tǒng)的默認(rèn)語(yǔ)言環(huán)境是英文環(huán)境,,這樣就會(huì)出現(xiàn)亂碼,,分析過(guò)程如下:源文件編碼格式為GB18030,默認(rèn)編譯,,也采用GB18030讀取源文件,,正常轉(zhuǎn)換為UTF-8,生成class文件,,運(yùn)行時(shí)沒(méi)有進(jìn)行特殊設(shè)置,,語(yǔ)言環(huán)境為英文環(huán)境,,默認(rèn)編碼為ISO8859-1,這樣在輸出中文的時(shí)候會(huì)把正常的UTF-8表示的漢字用ISO8859-1的字符集去編碼生成字節(jié)流,,因?yàn)镮SO8859-1不支持漢字,,結(jié)果輸出的都是’?’,??墒沁@個(gè)時(shí)候卻發(fā)現(xiàn),由外界輸入給java程序的中文字符,,卻能正常輸出,,這又是為什么,其實(shí)這個(gè)也是運(yùn)行時(shí)的默認(rèn)字符集ISO8859-1造成的,,Java程序運(yùn)行時(shí),,在讀取外部進(jìn)入的字節(jié)流的時(shí)候,如果使用默認(rèn)的讀取方式,,也是使用ISO8859-1的字符集進(jìn)行解碼處理,,這樣中間的處理過(guò)程中,中文都已經(jīng)不是原來(lái)的中文了,,也就是說(shuō)我們這個(gè)時(shí)候處理根本不是我們認(rèn)為的中文,,而是一對(duì)亂碼,雖然是亂碼,,但是其中的信息卻沒(méi)有丟失,,在處理完后,在經(jīng)過(guò)一次ISO8859-1的編碼,,又還原為正常的GB18030的編碼輸出,,所有沒(méi)有出現(xiàn)亂碼。我們以前的解決方法是,,在編譯原文件的時(shí)候指定參數(shù)-encoding ISO8859-1,,讓編譯器用ISO8859-1的字符集去解碼源文件編譯,然后運(yùn)行程序,,這時(shí)再輸出程序的內(nèi)部中文字符串也不是亂碼了,。看起來(lái)一切都解決了,,可是卻沒(méi)有從根本上解決問(wèn)題,,class文件變得比平常大很多,程序中用到中文越多,,class文件變大的越快,。而且其中的中文信息也變味了。

另一個(gè)問(wèn)題,,如果我們正常編譯程序,,在AIX系統(tǒng)上線設(shè)定為中文環(huán)境,,然后再運(yùn)行Java程序,這樣既不會(huì)使程序變大,,也不會(huì)使中文變味,,可是用了一段時(shí)間又發(fā)現(xiàn)問(wèn)題了,處理過(guò)程中如果遇到偏僻的中文字,,還是亂碼,,原因是AIX的中文環(huán)境使用的字符集是IBM-eucCN,我認(rèn)為可能是這個(gè)字符集缺少偏僻漢字,,無(wú)法解釋其內(nèi)容,,所以偏僻字變成了亂碼了。

最后的解決辦法是,,在Windows中文環(huán)境下正常編寫原程序,,用默認(rèn)的方式編譯生成class文件,或者編譯時(shí)指定參數(shù)-encoding GB18030,,這樣漢字都能正常解釋并轉(zhuǎn)換為UTF-8存儲(chǔ)在class文件中,,在運(yùn)行的時(shí)候,我們需要制定參數(shù),,java –Dfile.encoding=GB18030 。,。,。。,。,,系統(tǒng)環(huán)境使用默認(rèn)英文即可,這樣JVM就不會(huì)根據(jù)系統(tǒng)的環(huán)境設(shè)定默認(rèn)字符集,,而是所有輸入輸出都使用我們指定的字符集,,這樣不但解決了英文環(huán)境下的中文輸出問(wèn)題,而且還解決了偏僻字的顯示問(wèn)題,。

最后附上漢字的轉(zhuǎn)碼過(guò)程:

1.‘中文’的GB18030編碼為d6 d0 ce c4 對(duì)應(yīng)java源碼文件

經(jīng)過(guò)ISO8859-1解碼為UTF-8為81 30 89 30 81 30 88 34 81 30 88 32 81 30 87 32 對(duì)應(yīng)編譯過(guò)程

經(jīng)過(guò)ISO8859-1編碼為d6 d0 ce c4 對(duì)應(yīng)Java程序輸出漢字的過(guò)程

d6 d0 ce c4經(jīng)GB18030解釋為‘中文’二字 對(duì)應(yīng)系統(tǒng)顯示漢字的過(guò)程,。

在這個(gè)過(guò)程中,雖然中間出現(xiàn)了亂碼,,但是信息沒(méi)有丟,,最后還是能還原為中文的,是比較蹩腳的處理過(guò)程,。

2. ‘中文’二字的UTF-8編碼為e4 b8 ad e6 96 87,,對(duì)應(yīng)正常編譯后的class文件存儲(chǔ)內(nèi)容

經(jīng)過(guò)ISO8859-1編碼為3f 3f,已經(jīng)出錯(cuò),,丟失信息,,對(duì)應(yīng)java程序漢字輸出過(guò)程

3f 3f經(jīng)GB18030解釋為漢字為,??,,亂碼,,無(wú)法還原, 對(duì)應(yīng)系統(tǒng)顯示漢字的過(guò)程

這個(gè)過(guò)程中,信息丟失,,是個(gè)完全錯(cuò)誤的處理過(guò)程,。

3. ‘中文’的GB18030編碼為d6 d0 ce c4 對(duì)應(yīng)java源碼文件

經(jīng)過(guò)GB18030解碼為UTF-8為e4 b8 ad e6 96 87 對(duì)應(yīng)編譯過(guò)程

經(jīng)過(guò)GB18030編碼為d6 d0 ce c4 對(duì)應(yīng)Java程序輸出漢字的過(guò)長(zhǎng)

d6 d0 ce c4經(jīng)GB18030解釋為‘中文’二字 對(duì)應(yīng)系統(tǒng)顯示漢字的過(guò)程。

這個(gè)過(guò)程是最為理想的處理過(guò)程,,沒(méi)有丟失信息,,也沒(méi)有出現(xiàn)任何蹩腳的信息。

java亂碼的根本原因就是:java可以設(shè)置字符編碼的地方太多,,只要有不統(tǒng)一的地方就有出現(xiàn)亂碼,。

----------------------------------------------------------------------------------------------------------------------------------

*************************************java、jsp中設(shè)置編碼******************************************/ 

首先說(shuō)在java里那些地方能夠設(shè)置編碼 

開(kāi)發(fā)工具會(huì)有好多地方設(shè)置編碼這個(gè)不解少了,,這里不介紹了,。 

下面兩種設(shè)置編碼格式方法適用于jsp頁(yè)面(*.jsp) 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> 

<%@ page contentType="text/html; charset=UTF-8" %> 

下面方式適合于jsp、servlet,、action中(*.java) 

request.setCharacterEncoding("UTF-8"); 

response.setCharacterEncoding("UTF-8"); 

下面適合html頁(yè)面(*.htm;*.html) 

Tomcate設(shè)置編碼(server.xml) 

mysql設(shè)置編碼命令 

SET character_set_client = utf8; 

SET character_set_connection = utf8; 

SET character_set_database = utf8; 

SET character_set_results = utf8;/*這里要注意很有用*/ 

SET character_set_server = utf8; 

SET collation_connection = utf8_bin; 

SET collation_database = utf8_bin; 

SET collation_server = utf8_bin; 

my.ini中配置默認(rèn)編碼 

default-character-set=utf8 

連接數(shù)據(jù)庫(kù)設(shè)置編碼 

jdbc:mysql://192.168.0.5:3306/test?characterEncoding=utf8 

/*****************************************java與mysq編碼對(duì)應(yīng)****************************************/ 

java中的常用編碼UTF-8;GBK;GB2312;ISO-8859-1; 

對(duì)應(yīng)mysql數(shù)據(jù)庫(kù)中的編碼utf8;gbk;gb2312;latin1 

/********************************************過(guò)濾器使用*********************************************/ 

//過(guò)濾器設(shè)置編碼過(guò)濾(SetCharacterEncodingFilter.java) 

package com.sorc; 

import java.io.*; 

import javax.servlet.*; 

import javax.servlet.http.*; 

public class SetCharacterEncodingFilter extends HttpServlet implements Filter{ 

private FilterConfig filterConfig; 

private String encoding=null; 

//Handle the passed-in FilterConfig 

public void init(FilterConfig filterConfig){ 

this.filterConfig=filterConfig; 

encoding=filterConfig.getInitParameter("encoding"); 

//Process the request/response pair 

public void doFilter(ServletRequest request,ServletResponse response,FilterChain filterChain){ 

try{ 

request.setCharacterEncoding(encoding); 

filterChain.doFilter(request,response); 

} catch(ServletException sx){ 

filterConfig.getServletContext().log(sx.getMessage()); 

} catch(IOException iox){ 

filterConfig.getServletContext().log(iox.getMessage()); 

//Clean up resources 

public void destroy(){ 

//web.xml配置過(guò)濾器方法(web.xmd) 

setcharacterencodingfilter 

com.sorc.SetCharacterEncodingFilter 

encoding 

utf8 

setcharacterencodingfilter 

/* 

/************************有了上面的基礎(chǔ)下面試完滿解決方案*****************************************/ 

1.使用GBK編碼的解決方案 

這個(gè)最簡(jiǎn)單 遇到設(shè)置編碼的地方就是用GBK數(shù)據(jù)庫(kù)gbk 然后在使用個(gè)過(guò)濾器過(guò)濾編碼為gbk一切搞定,。 

效果為添加數(shù)據(jù)無(wú)亂碼 讀出無(wú)亂碼 數(shù)據(jù)庫(kù)管理工具無(wú)亂碼 到處sql結(jié)構(gòu)和數(shù)據(jù)無(wú)亂碼 

2.使用UTF-8編碼解決方案 

所有編碼都設(shè)置為UTF-8 

數(shù)據(jù)庫(kù)編碼utf8 

設(shè)置過(guò)濾器編碼utf8 

數(shù)據(jù)庫(kù)連接?characterEncoding=utf8 

然后在數(shù)據(jù)庫(kù)管理工具或mysql命令行 運(yùn)行 SET character_set_results = gbk; 

效果為添加數(shù)據(jù)無(wú)亂碼 讀出無(wú)亂碼 數(shù)據(jù)庫(kù)管理工具無(wú)亂碼 到處sql結(jié)構(gòu)和數(shù)據(jù)時(shí)存在亂碼 

3.頁(yè)面使用UTF8 數(shù)據(jù)庫(kù)使用latin1的解決方案 

jap java tomcat 設(shè)置為UTF-8 

過(guò)濾器 utf8 

數(shù)據(jù)庫(kù)連接?characterEncoding=latin1 

數(shù)據(jù)庫(kù)其他latin1 

然后在數(shù)據(jù)庫(kù)管理工具或mysql命令行 運(yùn)行 SET character_set_results = gbk; 

效果為添加數(shù)據(jù)無(wú)亂碼 讀出無(wú)亂碼 數(shù)據(jù)庫(kù)管理工具無(wú)亂碼 到處sql結(jié)構(gòu)和數(shù)據(jù)時(shí)存在亂碼 

以上都不需要頁(yè)面或java代碼中手動(dòng)轉(zhuǎn)碼

----------------------------------------------------------------------------------------------------------------------------------

一、JSP頁(yè)面顯示亂碼二,、表單提交中文時(shí)出現(xiàn)亂碼三,、數(shù)據(jù)庫(kù)連接

大家在JSP的開(kāi)發(fā)過(guò)程中,經(jīng)常出現(xiàn)中文亂碼的問(wèn)題,,可能一至困擾著您,,我現(xiàn)在把我在JSP開(kāi)發(fā)中遇到的中文亂碼的問(wèn)題及解決辦法寫出來(lái)供大家參考。

一,、JSP頁(yè)面顯示亂碼

下面的顯示頁(yè)面(display.jsp)就出現(xiàn)亂碼:

JSP的中文處理

<%

out.print("JSP的中文處理");

%>

對(duì)不同的WEB服務(wù)器和不同的JDK版本,,處理結(jié)果就不一樣。原因:服務(wù)器使用的編碼方式不同和瀏覽器對(duì)不同的字符顯示結(jié)果不同而導(dǎo)致的,。解決辦法:在 JSP頁(yè)面中指定編碼方式(gb2312),即在頁(yè)面的第一行加上:<%@ page contentType="text/html; charset=gb2312"%>,,就可以消除亂碼了。完整頁(yè)面如下:

<%@ page contentType="text/html; charset=gb2312"%>

JSP的中文處理

<%

out.print("JSP的中文處理");

%>

二,、表單提交中文時(shí)出現(xiàn)亂碼

下面是一個(gè)提交頁(yè)面(submit.jsp),,代碼如下:

JSP的中文處理

下面是處理頁(yè)面(process.jsp)代碼:

<%@ page contentType="text/html; charset=gb2312"%>

JSP的中文處理

<%=request.getParameter("name")%>

如果submit.jsp提交英文字符能正確顯示,如果提交中文時(shí)就會(huì)出現(xiàn)亂碼,。原因:瀏覽器默認(rèn)使用UTF-8編碼方式來(lái)發(fā)送請(qǐng)求,,而UTF- 8和 GB2312編碼方式表示字符時(shí)不一樣,這樣就出現(xiàn)了不能識(shí)別字符。解決辦法:通過(guò)request.seCharacterEncoding ("gb2312")對(duì)請(qǐng)求進(jìn)行統(tǒng)一編碼,,就實(shí)現(xiàn)了中文的正常顯示,。修改后的process.jsp代碼如下:

<%@ page contentType="text/html; charset=gb2312"%>

<%

request.seCharacterEncoding("gb2312");

%>

JSP的中文處理

<%=request.getParameter("name")%>

三、數(shù)據(jù)庫(kù)連接出現(xiàn)亂碼

只要涉及中文的地方全部是亂碼,,解決辦法:在數(shù)據(jù)庫(kù)的數(shù)據(jù)庫(kù)URL中加上

useUnicode=true&characterEncoding=GBK 就OK了,。

四、數(shù)據(jù)庫(kù)的顯示亂碼

在mysql4.1.0中,varchar類型,,text類型就會(huì)出現(xiàn)中文亂碼,,對(duì)于varchar類型把它設(shè)為binary屬性就可以解決中文問(wèn)題,對(duì)于text類型就要用一個(gè)編碼轉(zhuǎn)換類來(lái)處理,,實(shí)現(xiàn)如下:

public class Convert {

/** 把ISO-8859-1碼轉(zhuǎn)換成GB2312

*/

public static String ISOtoGB(String iso){

String gb;

try{

if(iso.equals("") || iso == null){

return "";

}

else{

iso = iso.trim();

gb = new String(iso.getBytes("ISO-8859-1"),"GB2312");

return gb;

}

}

catch(Exception e){

System.err.print("編碼轉(zhuǎn)換錯(cuò)誤:"+e.getMessage());

return "";

}

}

}

把它編譯成class,,就可以調(diào)用Convert類的靜態(tài)方法ISOtoGB()來(lái)轉(zhuǎn)換編碼。

如果你還有什么不懂之處:我給大家推薦一個(gè)好的JSP-JAVA網(wǎng)站:

http://www.phy./dsp/

總結(jié):

1.   在jsp中<%@ page contentType="text/html; charset=A" %>如果指定了,,那么在改jsp中所有構(gòu)造的String(不是引用),,如果沒(méi)有指定編碼,那么這些String的編碼是A的,。

從request的得到的String如果沒(méi)有指定request的編碼的話,,他是iso-8859-1的

從別的地方得到的String是使用原來(lái)初始的編碼的,比如從數(shù)據(jù)庫(kù)得到String,如果數(shù)據(jù)庫(kù)的編碼是B,那么該String的編碼是B而不是A的,,也不是系統(tǒng)默認(rèn)的,。

此時(shí),如果要輸出的String的編碼不是A,那么,,很可能顯示亂碼的,,所以首先要將String正確轉(zhuǎn)化為編碼A的String,然后輸出。

2.   在jsp中<%@ page contentType="text/html; charset=A" %>沒(méi)有指定,,那么相當(dāng)于指定了<%@ page contentType="text/html; charset=ISO-8859-1" %>

3. Servelte中如果執(zhí)行了像 response.setContentType("text/html;charset=A");説明將response的字符輸出流編碼設(shè)置為A,所有要輸出的String的編碼要轉(zhuǎn)化為A的,否則會(huì)得到亂碼的,。

Servelet中從request得到的String的編碼和jsp中一樣的,,但是在servlet java文件中構(gòu)造的String是使用的系統(tǒng)默認(rèn)的編

--------------------------------------------------------------------------

根本解決辦法 所有地方都設(shè)置成GBK

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多