一:設置編碼格式
1、JSP文件
charset=UTF-8 的作用是指定JSP向客戶端輸出的編碼方式為"UTF-8",pageEncoding="UTF-8" 為了讓JSP引擎能正確地解碼含有中文字符的JSP頁面,這在LINUX中很有效,request.setCharacterEncoding("UTF-8") 則是對請求進行了中文編碼。
1 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> 2 <% request.setCharacterEncoding("UTF-8"); %>
2、XML文件
<?xml version="1.0" encoding="UTF-8"?>
3、HTML文件(也稱HTTP BODY)
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
4、Tomcat
通常在配置文件server.xml文件中更改編碼格式。默認編碼為ISO-8859-1 。URIEncoding設置編碼格式,useBodyEncodingForURI=true 則是使用Header 中 ContentType 中定義的編碼格式
<Connector port="8080" useBodyEncodingForURI="true" URIEncoding="UTF-8" />
5、訪問數據庫都是通過客戶端 JDBC 驅動來完成,用 JDBC 來存取數據要和數據的內置編碼保持一致,可以通過設置 JDBC URL
MySQL:url="jdbc:mysql://localhost:3306/DB?useUnicode=true&characterEncoding=UTF-8"
二:經常涉及到編碼操作的
1、I/O
涉及到編碼的地方一般都在字符到字節或者字節到字符的轉換上,而需要這種轉換的場景主要是在 I/O 的時候,這個 I/O 包括磁盤 I/O 和網絡 I/O,關於網絡 I/O 部分在后面將主要以 Web 應用為例介紹。下圖是 Java 中處理 I/O 問題的接口:
Reader 類是 Java 的 I/O 中讀字符的父類,而 InputStream 類是讀字節的父類,InputStreamReader 類就是關聯字節到字符的橋梁,它負責在 I/O 過程中處理讀取字節到字符的轉換,而具體字節到字符的解碼實現它由 StreamDecoder 去實現,在 StreamDecoder 解碼過程中必須由用戶指定 Charset 編碼格式。值得注意的是如果你沒有指定 Charset,將使用本地環境中的默認字符集,例如在中文環境中將使用 GBK 編碼。
寫的情況也是類似,字符的父類是 Writer,字節的父類是 OutputStream,通過 OutputStreamWriter 轉換字符到字節。如下圖所示:
同樣 StreamEncoder 類負責將字符編碼成字節,編碼格式和默認編碼規則與解碼是一致的。
編碼示例:
1 String file = "c:/stream.txt"; 2 String charset = "UTF-8"; 3 // 寫字符換轉成字節流 4 FileOutputStream outputStream = new FileOutputStream(file); 5 OutputStreamWriter writer = new OutputStreamWriter(outputStream, charset); 6 try { 7 writer.write("這是要保存的中文字符"); 8 } finally { 9 writer.close(); 10 } 11 // 讀取字節轉換成字符 12 FileInputStream inputStream = new FileInputStream(file); 13 InputStreamReader reader = new InputStreamReader(inputStream, charset); 14 StringBuffer buffer = new StringBuffer(); 15 char[] buf = new char[64]; 16 int count = 0; 17 try { 18 while ((count = reader.read(buf)) != -1) { 19 buffer.append(buffer, 0, count); 20 } 21 } finally { 22 reader.close(); 23 }
2、內存中操作
在 Java 開發中除了 I/O 涉及到編碼外,最常用的應該就是在內存中進行字符到字節的數據類型的轉換,Java 中用 String 表示字符串,所以 String 類就提供轉換到字節的方法,也支持將字節轉換為字符串的構造函數。如下代碼示例:
1 String s = "這是一段中文字符串"; 2 byte[] byte = s.getBytes("ISO-8859-1"); 3 String str = new String(byte,"UTF-8");
Charset 提供 encode 與 decode 分別對應 char[] 到 byte[] 的編碼和 byte[] 到 char[] 的解碼。編碼與解碼都在一個類中完成,通過 forName 設置編解碼字符集,這樣更容易統一編碼格式。如下代碼所示:
1 Charset charset = Charset.forName("UTF-8"); 2 ByteBuffer byteBuffer = charset.encode(string); 3 CharBuffer charBuffer = charset.decode(byteBuffer);
Java 中還有一個 ByteBuffer 類,它提供一種 char 和 byte 之間的軟轉換,它們之間轉換不需要編碼與解碼,只是把一個 16bit 的 char 格式,拆分成為 2 個 8bit 的 byte 表示,它們的實際值並沒有被修改,僅僅是數據的類型做了轉換。如下代碼所以:
1 ByteBuffer heapByteBuffer = ByteBuffer.allocate(1024); 2 ByteBuffer byteBuffer = heapByteBuffer.putChar(c);
3、Java Web
方法一:有web.xml的話,在xml中添加如下代碼:
1 <!-- 統一字符編碼 --> 2 <filter> 3 <filter-name>CharacterEncodingFilter</filter-name> 4 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 5 <init-param> 6 <param-name>encoding</param-name> 7 <param-value>utf-8</param-value> 8 </init-param> 9 <init-param> 10 <param-name>forceEncoding</param-name> 11 <param-value>true</param-value> 12 </init-param> 13 </filter> 14 15 <filter-mapping> 16 <filter-name>CharacterEncodingFilter</filter-name> 17 <url-pattern>/*</url-pattern> 18 </filter-mapping>
方法二:
1)接收參數
通常使用request.setCharacterEncoding設置接收參數的編碼格式
request.setCharacterEncoding("UTF-8")
如上述接收參數出現亂碼,可通過String進行編碼轉換。這個也是常用的解決亂碼方法
String value = new String(request.getParameter(name).getBytes("ISO-8859-1"), "UTF-8");
2)返回參數
只能用來設置out輸出流中所采用的編碼。優先級最高
response.setCharacterEncoding("UTF-8");
既可以設置out輸出流中字符的編碼方式,也可設置瀏覽器接收到這些字符后以什么編碼方式來解碼。等價於<%@ page contentType="text/html;charset=UTF-8" %>。優先級其次
response.setContentType("text/html;charset=UTF-8");
只能用來設置out輸出流中字符的編碼方式。優先級最低
response.setLocale(new java.util.Locale("ZH","CN"));
參考:
http://www.cnblogs.com/gdayq/p/5817367.html