JAva中国語文字化けしソリューションと経験


1.バイトとunicode JAvaカーネルはunicodeであり、classファイルでもありますが、ファイル/ストリームを含む多くのメディアの保存方法はバイトストリームを使用しています.したがってjavaは、これらのバイトをローを介して変換します.charはunicodeでbyteはバイトです.JAvaにおけるbyte/char相互回転の関数はsun.ioのパケットの間にある.ここでByteToCharConverterクラスは中スケジューリングで、あなたが使っているconvertorを教えてあげることができます.よく使われる2つの静的関数は  public static ByteToCharConverter getDefault(); 
public static ByteToCharConverter getConverter(String encoding); 
converterを指定しないと、現在のencodingが自動的に使用され、gbプラットフォームではgbk、enプラットフォームでは8859_が使用されます.1. byte ——〉char: 「あなた」のgbコードは:0 xc 4 e 3、unicodeは0 x 4 f 60  String encoding = "gb2312"; 
byte b[] = {(byte)'/u00c4',(byte)'/u00e3'}; 
ByteToCharConverter converter = ByteToCharConverter.getConverter(encoding); 
char c[] = converter.convertAll(b); 
for (int i = 0; i < c.length; i++) { 
System.out.println(Integer.toHexString(c[i])); 

の結果は何ですか?0x4f60 encoding=「8859_1」の場合、結果は何ですか?0x00c4,0x00e3 コードが  byte b[] = {(byte)'/u00c4',(byte)'/u00e3'}; 
ByteToCharConverter converter = ByteToCharConverter. getDefault(); 
char c[] = converter.convertAll(b); 
for (int i = 0; i < c.length; i++) { 
System.out.println(Integer.toHexString(c[i])); 

の結果は何ですか?プラットフォームのコードによって異なります.  char ——〉byte: 
String encoding = "gb2312"; 
char c[] = {'/u4f60'}; 
CharToByteConverter converter = CharToByteConverter.getConverter(encoding); 
byte b[] = converter.convertAll(c); 
for (int i = 0; i < b.length; i++) { 
System.out.println(Integer.toHexString(b[i])); 

の結果は何ですか?0x00c4,0x00e3 encoding=「8859_1」の場合、結果は何ですか?0x3f コードが  String encoding = "gb2312"; 
char c[] = {'/u4f60'}; 
CharToByteConverter converter = CharToByteConverter.getDefault(); 
byte b[] = converter.convertAll(c); 
for (int i = 0; i < b.length; i++) { 
System.out.println(Integer.toHexString(b[i])); 

の結果は何ですか?プラットフォームのコードによって異なります. 多くの中国語の問題はこの2つの最も簡単なクラスから派生したものだ.しかし、encodingの入力を直接サポートしていないクラスが多く、多くの不便をもたらしています.多くのプログラムは珍しくencodingを使い、defaultのencodingを直接使うので、移植に多くの困難をもたらしました. 2.utf-8 utf-8はunicodeに一つ一つ対応しており、その実現は簡単です 7位のunicode:0___ 11位のunicode:1 1 0__1 0 _ _ _ _ _ _ 16位のunicode:1 1 1 0__1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 21位のunicode:1 1 1 1 0_1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ ほとんどの場合、16ビット以下のunicodeのみが使用されます. 「あなた」のgbコードは:0 xc 4 e 3、unicodeは0 x 4 f 60 0 xc 4 e 3のバイナリ: 1100 ,0100 ,1110 ,0011 2人だけが2人の符号化で並んでいたが、7位が0ではないので「?」 0 x 4 f 60のバイナリ: 0100 ,1111 ,0110 ,0000 utf-8で補完し、次のようになります. 1110 ,0100 ,1011 ,1101 ,1010 ,0000 e4--bd-- a0 すると、0 xe 4,0 xbd,0 xa 0が返されます. 3.stringとbyte[] stringはコアがchar[]であるがbyteをstringに変換するには符号化されなければならない.string.length()は実はchar配列の長さであり,異なる符号化を用いると誤分し,ハッシュや文字化けしを引き起こす可能性が高い. 例:  String encoding = “”; 
byte [] b={(byte)'/u00c4',(byte)'/u00e3'}; 
String str=new String(b,encoding);   
encoding=8859_1は、2文字ありますが、encoding=gb 2312は1文字しかないという問題は、ページング処理でよく発生します. 4.Reader,Writer/InputStream,OutputStream ReaderとWriterコアはchar、InputStreamとOutputStreamコアはbyteです.しかしReaderとWriterの主な目的はcharをInputStream/OutputStreamと読み書きすることである. 例: ファイルtest.txtには「あなた」の字が1つしかありません.0 xc 4,0 xe 3  String encoding = "gb2312"; 
InputStreamReader reader = new InputStreamReader(new FileInputStream( 
"text.txt"), encoding); 
char c[] = new char[10]; 
int length = reader.read(c); 
for (int i = 0; i < length; i++) { 
System.out.println(c[i]); 

の結果は何ですか?あなた encoding="8859_1"の場合、結果は何ですか??認識していないことを示す2文字. 逆の例は自分で作る. 5.javaのコンパイラについて理解する : javac ?encoding 私たちはよくencodingというパラメータを使用しません.実はencodingというパラメータはプラットフォーム間での操作にとって重要です.encodingが指定されていない場合は、システムのデフォルトencodingに従って、gbプラットフォームはgb 2312、英語プラットフォームはiso 8859_1. JAvaのコンパイラは実際にsun.tools.javac.mainを呼び出すクラスで、ファイルをコンパイルします.このクラスにはcompile関数の間にencodingの変数があります.-encodingのパラメータは実際にencoding変数に直接伝わります.コンパイラはこの変数に基づいてjavaファイルを読み出し、utf-8形式でclassファイルにコンパイルします. 例コード:  String str = " "; 
FileWriter writer = new FileWriter("text.txt"); 
write.write(str); 
writer.close(); 

gb 2312でコンパイルすると、e 4 bd a 0のフィールドが見つかります. 8859_を使うと1コンパイル、00 c 4 00 e 3のバイナリ: 0000,0000 ,1100,0100 ,0000,0000 ,1110,0011 各文字は7ビットより大きいので、11ビットで符号化されます. 1100,0001,1000,0100,1100,0011,1010,0011 c1-- 84-- c3--  a3 c 1 84 c 3 a 3が見つかります. しかし、私たちはこのパラメータを無視することが多いので、プラットフォームにまたがる問題があります. サンプルコードは中国語プラットフォームでコンパイルしzhclassを生成する サンプルコードは英語プラットフォームでコンパイルし、enclassを出力します. (1).zhclassは中国語プラットフォームでokを実行するが、英語プラットフォームではだめである (2).enclassは英語プラットフォームでokを実行するが,中国語プラットフォームではだめである. 理由: (1).中国語プラットフォームでコンパイルした後、strは実行状態のchar[]が0 x 4 f 60であり、中国語プラットフォームで実行され、filewriterのデフォルト符号化はgb 2312であるため、chartobyteconverterはgb 2312を呼び出すconverterを自動的に使用し、strをbyteに変換してfileoutputstreamに入力し、0 xc 4,0 xe 3をファイルに入れた. ただし、英語プラットフォームの場合、chartobyteconverterのデフォルト値は8859_です.1、filewriterは自動的に8859_を呼び出します.1 strを変換しますが、彼は説明できないので、「?」と出力します. (2).英語プラットフォームでコンパイルした後、strは実行状態のchar[]が0 x 00 c 4 0 x 00 e 3であり、中国語プラットフォームで実行され、中国語が認識できないため、現れる?? 英語プラットフォームでは、0 x 00 c 4->0 xc 4,0 x 00 e 3->0 xe 3のため、0 xc 4,0 xe 3がファイルに格納されます. 6.その他の理由: <%@ page contentType="text/html; charset=GBK"%> ブラウザの表示符号化を設定し、responseのデータがutf 8符号化であれば表示は乱符号化されるが、乱符号化は上記の理由とは異なる. 7.コードが発生した箇所 : データベースからjavaプログラムbyte——〉char javaプログラムからデータベースchar——〉byte ファイルからjavaプログラムbyte——〉char javaプログラムからファイルcharまで——〉byte javaプログラムからページ表示char——〉byte ページformからjavaプログラムbyteにデータを提出する——〉char ストリームからjavaプログラムbyte——〉char javaプログラムからストリームcharまで——〉byte 謝志鋼の解決方法: 私はフィルタを構成する方法を使って中国語の文字化けしを解決しました.  <web-app> 
<filter> 
<filter-name>RequestFilter</filter-name> 
<filter-class>net.golden.uirs.util.RequestFilter</filter-class> 
<init-param> 
<param-name>charset</param-name> 
<param-value>gb2312</param-value> 
</init-param> 
</filter> 
<filter-mapping> 
<filter-name>RequestFilter</filter-name> 
<url-pattern>*.jsp</url-pattern> 
</filter-mapping> 
</web-app> 


public void doFilter(ServletRequest req, ServletResponse res, 
FilterChain fChain) throws IOException, ServletException { 
HttpServletRequest request = (HttpServletRequest) req; 
HttpServletResponse response = (HttpServletResponse) res; 
HttpSession session = request.getSession(); 
String userId = (String) session.getAttribute("userid"); 
req.setCharacterEncoding(this.filterConfig.getInitParameter("charset")); // ? 
byte ——〉char encoding 
try { 
if (userId == null || userId.equals("")) { 
if (!request.getRequestURL().toString().matches( 
".*/uirs/logon/logon(Controller){0,1}//x2Ejsp$")) { 
session.invalidate(); 
response.sendRedirect(request.getContextPath() + 
"/uirs/logon/logon.jsp"); 


else { //  
if (!net.golden.uirs.util.UirsChecker.check(userId, " ", 
net.golden.uirs.util.UirsChecker.ACTION_DO)) { 
if (!request.getRequestURL().toString().matches( 
".*/uirs/logon/logon(Controller){0,1}//x2Ejsp$")) { 
response.sendRedirect(request.getContextPath() + 
"/uirs/logon/logonController.jsp"); 




catch (Exception ex) { 
response.sendRedirect(request.getContextPath() + 
"/uirs/logon/logon.jsp"); 

fChain.doFilter(req, res);