总结:只要把握文件本来的编码以及读取时的编码,乱码问题就不难解决。

页面编码URF-8,get,post提交的编码由filter配置UTF-8,中间件如tomcat server.xml配置UTF-8,数据库UTF-8等。

注意:Java 程序里 “字节” 到 “字符”时 (编码) 需要指定编码格式,
如 byte[]---String需要,file,xml文件-----到java里的String 也需要,此时未指定编码格式,会用默认gbk,如果指定了编码格式就会按照指定格式生成String字符。
如下lastE2.xml 指定了 按照UTF-8 来Reader生成字符串:
new BufferedReader(new InputStreamReader(
new FileInputStream(PyFrontServiceImpl.class.getClassLoader().
getResource("py\\lastE2.xml").toURI().getPath()),"UTF-8"));

如下  
InputSource   未指定字节生成字符的编码格式,那么就是默认的。
InputSource source = new InputSource(new ByteArrayInputStream(resultStr.getBytes()));
如果要指定可以增加:  source.setEncoding("UTF-8"); 该方法对字符无效,因为字符流创建时会指定编码格式,或已经用默认的格式指定了。
并且,使用发现在tomcat下会出现以下错误: Parse Fatal Error at line 1 column 86: Invalid byte 2 of 2-byte UTF-8 sequence.
替换为字符流就OK:
 InputSource source = new InputSource(new StringReader(utf8String));// utf8String已经是UTF-8了,所以不用再次指定
所以,在获取 字节 到生成 字符 过程中为了避免乱码,我们一定要制定编码格式,UTF-8。

JVM编码和默认创建对象时的编码(转):





如果在正體中文Windows中,你使用以下的程式來讀取內含「測試」文字的檔案:
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(new FileReader(args[0]));
System.out.println(reader.readLine());
reader.close();
}
}

如果該檔案是使用MS950處理,那上面的程式可以正確讀出並顯示「測試」,如果文字檔案不是MS950,那就會顯示亂碼,例如,假設是UTF-8儲存「測試」的文字檔案:
C:\workspace>java Main sample.txt
皜祈岫

有些API若不指定編碼,通常會使用JVM預設編碼,預設會與作業系統預設編碼相同,可以使用Charset.defaultCharset()取得預設編碼,在API中,有許多API若不指定編碼,就會採用JVM預設編碼,像是String建構式、getBytes()方法或這邊看到的FileReader等。

為了要正確讀取文字檔案,你要使用InputStreamReader,將讀入的位元組指定編碼進行字串轉換。例如:
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader reader = new BufferedReader(
new InputStreamReader(new FileInputStream(args[0]), "UTF-8"));
System.out.println(reader.readLine());
reader.close();
}
}

在正體中文Windows中,如下執行這個程式讀取UTF-8的文字檔案就可以正確顯示「測試」:
C:\workspace>java Main sample.txt
測試

在啟動JVM時,其實可以使用-Dfile.encoding指定JVM預設編碼,例如:
C:\workspace>java -Dfile.encoding=UTF-8 Main sample.txt
皜祈岫

這次你看到了亂碼,這是因為System.out實際上是PrintStream實例,會使用JVM預設編碼輸出文字,就上例而言,System.out使用UTF-8輸出了文字,但你的Console顯示時是使用什麼編碼呢?

程式都是正確的,問題是出在Console,這不單是發生在Windows的Console,也常有程式設計人員指著IDE中的Console問,為什麼看到亂碼或問號,請改變一下你的Console顯示編碼!要不然,在程式中改變一下System.out的編碼處理:
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
System.setOut(new PrintStream(System.out, true, "Big5"));

BufferedReader reader = new BufferedReader(new FileReader(args[0]));
System.out.println(reader.readLine());
reader.close();
}
}

在這個程式中,不指定FileReader的讀取,所以會使用JVM預設編碼,而System.out會用Big5,所以讀取UTF-8文字檔案時,若如下:

C:\workspace>java -Dfile.encoding=UTF-8 Main sample.txt
測試

由於指定了JVM預設編碼為UTF-8,所以程式中的FileReader會用UTF-8讀取文字檔案,而輸出至主控台時,使用Big5編碼進行處理。

使用某些API時,最好明確指定使用何種編碼,或者至少,要確認你的JVM預設編碼到底是什麼,以及API是否使用JVM預設編碼。