最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java亂碼問題解決方法_動力節(jié)點Java學(xué)院整理

 更新時間:2017年07月20日 10:39:55   投稿:mrr  
開發(fā)java應(yīng)用出現(xiàn)亂碼是很常見的,畢竟現(xiàn)在unicode的使用還不是很廣泛,下面給大家分享Java亂碼問題解決方法,感興趣的朋友一起看看吧

1.文件頁面編碼導(dǎo)致的亂碼。

每一個文件(java,js,jsp,html等)都有其本身的編碼格式,文件中的代碼在一種編碼中顯示正常,在另外一種編碼下就會顯示出亂碼。

在Eclipse中,每一個工程都會有編碼格式(Text file encoding), 一般默認(rèn)為GBK。而一個比較好的編程習(xí)慣是新建一個項目,優(yōu)先把項目的編碼設(shè)為UTF-8。

這樣做的原因很簡單,UTF-8包含全世界所有國家需要用到的字符,是國際編碼,通用性強。幾種常見的字符集,GBK,GB2312,UTF-8之間的關(guān)系如下:

GBK是國家標(biāo)準(zhǔn)GB2312基礎(chǔ)上擴容后兼容GB2312的標(biāo)準(zhǔn)。GBK、GB2312等與UTF8之間都必須通過Unicode編碼才能相互轉(zhuǎn)換

2.不同字符集的字符串轉(zhuǎn)換時導(dǎo)致的亂碼。

每一個String,底層實現(xiàn)都是用一個byte數(shù)組存儲,使用不同的字符集,存儲的數(shù)組長度當(dāng)然就不同。如果不使用同一種字符集進行解碼,就一定會出現(xiàn)亂碼。

例如如下代碼:

Java代碼  

import java.io.UnsupportedEncodingException; 
import java.nio.charset.Charset; 
public class TestCharset { 
  public static void main(String[] args) throws UnsupportedEncodingException {  
    String strChineseString = "中文"; 
    String encoding = System.getProperty("file.encoding"); 
    System.out.println("系統(tǒng)默認(rèn)的字符集是:" + encoding); 
    System.out.println(strChineseString.getBytes(Charset.forName("GBK")).length); 
    System.out.println(strChineseString.getBytes(Charset.forName("UTF-8")).length); 
    System.out.println(strChineseString.getBytes().length); 
  } 
} 

輸出結(jié)果為:

Java代碼  

1.系統(tǒng)默認(rèn)的字符集是:UTF-8  

2.4  
3.6  
4.6   

可以看出,使用GBK和UTF-8編碼,得到的byte數(shù)組長度不一樣,原因就是utf-8使用3個字節(jié)來編碼中文,而GBK使用2個字節(jié)來編碼中文。因為我的項目默認(rèn)使用UTF-8,所以使用不加參數(shù)的getBytes()得到的數(shù)組長度和使用UTF-8編碼的 字符串長度一樣。關(guān)于字符集的詳細(xì)知識可以參考第一部分中給出的文章地址。

 JDK中關(guān)于getBytes方法的描述:

 getBytes() 使用平臺的默認(rèn)字符集將此 String 編碼為 byte 序列,并將結(jié)果存儲到一個新的 byte 數(shù)組中。

 getBytes(Charset charset) 使用給定的 charset 將此 String 編碼到 byte 序列,并將結(jié)果存儲到新的 byte 數(shù)組。

每一個字符串底層都有自己的編碼方式。不過一旦調(diào)用getByte方法后,得到的byte數(shù)組就是使用某種特定字符集編碼后的數(shù)組,不需要再做多余的轉(zhuǎn)換。

當(dāng)?shù)玫缴厦娴腷yte數(shù)組后,就可以調(diào)用String的另外一個方法來生成需要轉(zhuǎn)碼的String了。

測試?yán)尤缦拢?/p>

Java代碼  

import java.io.UnsupportedEncodingException; 
import java.nio.charset.Charset; 
public class TestCharset { 
  public static void main(String[] args) throws UnsupportedEncodingException { 
    String strChineseString = "中文"; 
    byte[] byteGBK = null; 
    byte[] byteUTF8 = null; 
    byteGBK = strChineseString.getBytes(Charset.forName("GBK")); 
    byteUTF8 = strChineseString.getBytes(Charset.forName("utf-8")); 
    System.out.println(new String(byteGBK,"GBK")); 
    System.out.println(new String(byteGBK,"utf-8")); 
    System.out.println("**************************"); 
    System.out.println(new String(byteUTF8,"utf-8")); 
    System.out.println(new String(byteUTF8,"GBK")); 
  } 
} 

輸出結(jié)果為:

Java代碼  

1.中文  
2.����  
3.**************************  
4.中文  
5.涓枃  

可以看出,使用哪種字符集編碼一個String,在生成一個String的時候就必須使用相應(yīng)的編碼,否則就會出現(xiàn)亂碼。
簡單來講,只有滿足如下公式的String轉(zhuǎn)碼,才不會亂碼。

Java代碼  

String strSource = "你想要轉(zhuǎn)碼的字符串"; 
String strSomeEncoding = "utf-8";  //例如utf-8 
String strTarget = new String (strSource.getBytes(Charset.forName(strSomeEncoding)), strSomeEncoding);  

JDK中關(guān)于getBytes方法的描述:

String(byte[] bytes)  通過使用平臺的默認(rèn)字符集解碼指定的 byte 數(shù)組,構(gòu)造一個新的 String。 

String(byte[] bytes, Charset charset)  通過使用指定的 charset 解碼指定的 byte 數(shù)組,構(gòu)造一個新的 String。 

3.Socket網(wǎng)絡(luò)傳輸時導(dǎo)致的中文亂碼。

使用Socket進行通訊的時候,傳輸有多種選擇,可以使用PrintStream,也可以使用PrintWriter。傳輸英文還好,傳輸中文就可能出現(xiàn)亂碼問題。網(wǎng)上的說法很多,經(jīng)過實際測試,發(fā)現(xiàn)問題還在字節(jié)和字符的問題上面。

眾所周知,Java中分為字節(jié)流和字符流,字符(char)是16bit的,字節(jié)(BYTE)是8bit的。PrintStrean是寫入一串8bit的數(shù)據(jù)的。 PrintWriter是寫入一串16bit的數(shù)據(jù)的。 

String缺省是用UNICODE編碼,是16bit的。因此用PrintWriter寫入的字符串,跨平臺性好一些,PrintStream的可能會出現(xiàn)字符集亂碼。

可以這樣理解上面的話,PrintStream是用來操作byte, PrintWriter是用來操作Unicode, PrintStream一次讀8bit的話,如果遇到漢字(一個漢字占16bit),就可能會出現(xiàn)亂碼。一般需要處理中文時用PrintWriter好了。

最后網(wǎng)站測試,使用PrintWriter沒有出現(xiàn)亂碼。代碼如下:

Java代碼  

import java.io.BufferedReader; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.io.OutputStreamWriter; 
import java.io.PrintWriter; 
import java.net.Socket; 
public class TestSocket { 
  public static void main(String[] args) throws IOException { 
    Socket socket = new Socket(); 
    DataOutputStream dos = null; 
    PrintWriter pw = null;    
    BufferedReader in = null; 
    String responseXml = "要傳輸?shù)闹形?; 
    //.......... 
    dos = new DataOutputStream(socket.getOutputStream()); 
    pw = new PrintWriter(new OutputStreamWriter(dos)); //不帶自動刷新的Writer      
    pw.println(responseXml); 
    pw.flush(); 
  } 
} 

需要注意的方面是,需要使用PrintWriter的println而不是write方法,否則服務(wù)器端會讀不到數(shù)據(jù)的。原因就是println會在輸出的時候在字符串后面加一個換行符,而write不會。 

4.JSP中顯示中文的亂碼。

有的時候JSP頁面在顯示中文的時候會有亂碼,大多數(shù)情況就是字符集配置和頁面編碼的問題。只要保證如下的幾個配置沒有問題,一般就不會有亂碼出現(xiàn)。

a.JSP頁面頂端添加如下語句:

Java代碼  

<%@ page contentType="text/html; charset=utf-8" language="java" errorPage="" %>  

b.在HTML的head標(biāo)簽中添加如下語句。

Java代碼  

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  

c.保證JSP的頁面編碼與上面兩個的charset相同,這點我有在文章的第一點說過。

上面的字符集可以根據(jù)需要自己靈活選擇,不一定非要utf-8。不過因為utf-8對各國語言,特別是中文支持較好,所以推薦使用。我就曾經(jīng)遇到過滘在GB2312編碼的頁面無法正常顯示的問題。

5.Post和Get傳遞中文,后臺獲取亂碼。

前臺傳遞中文也分為Get和Post方法。

a.Get方法的情況:

Get方法的時候主要是URL傳遞中文。

如果是在js文件中,可以使用如下代碼進行中文轉(zhuǎn)碼。

Js代碼  

var url ="http://www.baidu.com/s?industry=編碼" 
url = encodeURI(url);  

如果是在jsp文件中,則可以使用如下語句進行轉(zhuǎn)碼。
頁面開始引入:

Java代碼  

<%@ page import="java.net.URLEncoder" %>

      需要轉(zhuǎn)碼的地方使用URLEncoder進行編碼:

Js代碼  

<a href="xxxxx.xx?industry=<%=URLEncoder.encode(" rel="external nofollow" http://www.baidu.com/s?wd=編碼", "UTF-8")%>">  

無論使用哪種方法,在后臺獲取中文的時候都要使用如下代碼:

Java代碼  

request.setCharacterEncoding("utf-8"); 
String industry = new String( 
request.getParameter("industry ").getBytes("ISO8859-1"),"UTF-8");  

【注】

1.對于request,是指提交內(nèi)容的編碼,指定后可以通過getParameter()則直接獲得正確的字符串,如果不指定,則默認(rèn)使用iso8859-1編碼,為了統(tǒng)一,需要提交指定傳輸編碼。

2.上面代碼的第二句好像和第2條中給出的公式矛盾。我也糾結(jié)了好久,最后發(fā)現(xiàn)ISO8859-1是一種比較老的編碼,通常叫做Latin-1,屬于單字節(jié)編碼,正好和計算機最基礎(chǔ)的表示單位一致,因此使用它進行轉(zhuǎn)碼一般也沒有問題。

iso-8859-1是JAVA網(wǎng)絡(luò)傳輸使用的標(biāo)準(zhǔn)字符集,而gb2312是標(biāo)準(zhǔn)中文字符集,當(dāng)你作出提交表單等需要網(wǎng)絡(luò)傳輸?shù)牟僮鞯臅r候,就需要把 iso-8859-1轉(zhuǎn)換為gb2312字符集顯示,否則如果按瀏覽器的gb2312格式來解釋iso-8859-1字符集的話,由于2者不兼容,所以會是亂碼。為了省事,建議統(tǒng)一使用utf-8字符集。
b.POST方法的情況。 

對于Post的情況就比較簡單了,只需要在post的函數(shù)調(diào)用部分,制定post的header的字符集,如:

Js代碼  

xmlHttp.open("post", url , true); 
xmlHttp.setRequestHeader("Content-Type","text/xml; charset= utf-8");  
xmlHttp.send(param);  

其中param為要傳遞的參數(shù)。

后臺部分和get方法一樣,設(shè)置如下即可,注意傳輸和接受的字符集要統(tǒng)一。

 6.后臺向前臺傳遞中文亂碼。

在這里提供一個函數(shù),通過這個函數(shù)來發(fā)送信息,就不會出現(xiàn)亂碼,核心思想也是設(shè)置response流的字符集。函數(shù)代碼如下:

Java代碼  

/** 
 * @Function:writeResponse 
 * @Description:ajax方式返回字符串 
 * @param str:json 
 * @return:true:輸出成功,false:輸出失敗 
 */ 
public boolean writeResponse(String str){ 
  boolean ret = true; 
  try{ 
    HttpServletResponse response = ServletActionContext.getResponse(); 
    response.setContentType("text/html;charset=utf-8"); 
    PrintWriter pw = response.getWriter(); 
    pw.print(str); 
    pw.close(); 
  }catch (Exception e) { 
    ret = false; 
    e.printStackTrace(); 
  } 
  return ret; 
}   

7.下載文件時文件名亂碼。

下過下載的人都知道下載的文件容易出現(xiàn)亂碼,原因也是沒有對輸出流的編碼格式進行限定。

附上一段代碼,用來幫你完成無亂碼下載。

Java代碼  

HttpServletResponse response = ServletActionContext.getResponse(); 
response.setContentType("text/html;charset=utf-8"); 
response.reset(); 
String header = "attachment; filename=" + picName; 
   header = new String(header.getBytes(), "UTF-8"); 
   response.setHeader("Content-disposition", header); 

核心代碼就上幾句,注意第二句和第三句的reset的順序不能搞錯。

reset的作用是用來清空buffer緩存的,清空請求前部的一些空白行。 

以上只是做了比較簡單的總結(jié),具體亂碼有的時候可能是多個情況的組合,具體問題具體分析。如果錯誤歡迎指正。

相關(guān)文章

  • 聊聊注解@controller@service@component@repository的區(qū)別

    聊聊注解@controller@service@component@repository的區(qū)別

    這篇文章主要介紹了聊聊注解@controller@service@component@repository的區(qū)別,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java File類重要方法以及如何操作文件詳解

    java File類重要方法以及如何操作文件詳解

    這篇文章主要為大家介紹了java File類重要方法以及如何操作文件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-06-06
  • 詳解SpringMVC中的異常處理

    詳解SpringMVC中的異常處理

    這篇文章主要介紹了SpringMVC中的異常處理的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用SpringMVC,感興趣的朋友可以了解下
    2021-03-03
  • Java實現(xiàn)學(xué)生信息管理系統(tǒng)IO版本

    Java實現(xiàn)學(xué)生信息管理系統(tǒng)IO版本

    這篇文章主要為大家詳細(xì)介紹了Java實現(xiàn)學(xué)生信息管理系統(tǒng)IO版本,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Java設(shè)計模式之橋梁(Bridge)模式

    Java設(shè)計模式之橋梁(Bridge)模式

    這篇文章主要介紹了Java設(shè)計模式之橋梁(Bridge)模式,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)Java設(shè)計模式的小伙伴們有很好的幫助,需要的朋友可以參考下
    2021-05-05
  • MyBatis Plus 實現(xiàn)多表分頁查詢功能的示例代碼

    MyBatis Plus 實現(xiàn)多表分頁查詢功能的示例代碼

    這篇文章主要介紹了MyBatis Plus 實現(xiàn)多表分頁查詢功能,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • java字符串切割實例學(xué)習(xí)(獲取文件名)

    java字符串切割實例學(xué)習(xí)(獲取文件名)

    在Java中處理一些路徑相關(guān)的問題的時候,如要取出ie瀏覽器上傳文件的文件名,由于ie會把整個文件路徑都作為文件名上傳,需要用java.lang.String中的replaceAll或者split來處理,下面看看使用方法
    2013-12-12
  • 如何解決redis的NOAUTH Authentication required異常

    如何解決redis的NOAUTH Authentication required異常

    這篇文章主要介紹了Jedis異常解決:NOAUTH Authentication required,,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值
    2019-07-07
  • 深入解析StringBuffer和StringBuilder的區(qū)別

    深入解析StringBuffer和StringBuilder的區(qū)別

    以下是對java中StringBuffer與StringBuilder的區(qū)別進行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • Java MyBatis可視化代碼生成工具使用教程

    Java MyBatis可視化代碼生成工具使用教程

    這篇文章主要介紹了Java MyBatis可視化代碼生成工具使用教程,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-11-11

最新評論

台北县| 长治市| 延长县| 墨竹工卡县| 乌鲁木齐县| 常州市| 卓尼县| 彭泽县| 静海县| 仙游县| 凤山县| 苏尼特右旗| 错那县| 毕节市| 开平市| 银川市| 万山特区| 历史| 鹰潭市| 清水河县| 密山市| 团风县| 邵东县| 荣昌县| 贵德县| 黔西| 张家界市| 江门市| 全南县| 沙河市| 乡城县| 南雄市| 泰和县| 图木舒克市| 华安县| 怀宁县| 建平县| 石楼县| 岫岩| 望谟县| 廊坊市|