Java Web 開発の過程で、コード化けの問題によく遭遇します。コード化けの原因は、文字エンコーディングとデコード方法の不一致に要約できます。 。
文字化けの原因は文字エンコードとデコード方法が合っていないことなので、なぜエンコードしなければならないのでしょうか?これは、コンピューターにデータを保存する基本単位が 1 バイト、つまり 8 ビットであるため、表現できる最大文字数は 28=256 であり、私たちの現実社会に存在する文字 (中国語)文字、英語、その他の文字など)はこの数をはるかに超えているため、文字とバイトの間の競合を解決するには、文字をコンピュータに保存する前にエンコードする必要があります。
コンピュータにおける一般的なエンコード方式には、ASCII、ISO-8859-1、GB2312、UTF-16、UTF-8などがあります。
ASCIIコードはバイトの下位7ビットで表現されるので、表現できる最大文字数は27=128です。 ISO-8859-1 は、ASCII コードに基づく ISO 組織の拡張であり、ASCII コードと互換性があり、ほとんどの西ヨーロッパ文字をカバーします。 ISO8859-1 は 1 バイトで表現するため、最大 256 文字を表現できます。 GB2312 は 2 バイト エンコードを使用します。エンコード範囲は A1 ~ F7 です。A1 ~ A9 は記号領域、B0 ~ F7 は 6763 個の漢字を含む漢字領域です。 GBK は、GB2312 エンコーディングを拡張し、さらに多くの漢字を追加したものです。表現できる漢字は 21,003 文字です。 UTF-16 は、どの文字でも 2 バイトで表される固定長エンコーディング方式を使用します。これは、JAVA メモリ内の文字の格納形式でもあります。 UTF-16 とは対照的に、UTF-8 は可変長エンコード方式を使用し、さまざまな種類の文字を 1 ~ 6 バイトで構成できます。
以下に示すように、文字列「日向ヒナタ」を使用して、コンピューターでのさまざまなエンコード方法のエンコードを見てみましょう。
JAVA WEBのコード化け問題について、リクエストによるコード化けとレスポンスによるコード化けに分けて、それぞれのコード化けについて説明します。コード、つまり文字化けの原因を分析する必要があります。エンコード方式とデコード方式は何ですか。
リクエストによるコード化けについては、HTTPリクエストを解析し、そのエンコード方法を確認する必要があります。HTTPリクエストはGetリクエストとPostリクエストに分けて説明します。
Getリクエストの場合、ブラウザのデフォルトのリクエストメソッドであり、送信時にフォームを「Get」に設定した場合の送信メソッドです。 Firefox ブラウザを通じて次のように特定のコンテンツを確認します。
アドレス バーは次のとおりです。
リクエストのコンテンツは次のとおりです。
文字列はリクエスト ラインに保存され、WEB サーバーに送信されます。 「日向ヒナタ」のエンコードにより、ブラウザで文字列に使用されているエンコード方式が「UTF-8」であることがわかります。
サーバーのコードを見ると、文字化けが見られます (以下に示すように)。これは、サーバーがデフォルトで ISO-8859-1 を使用して文字列エンコードを受信した後にデータをデコードするため、エンコードとデコードが発生します。アプローチは一律ではありません。解決策の概略図は次のとおりです。
Java Web開発のプロセスでは、ハイパーリンクでパラメータを渡しますが、しばしば中国語の状況に遭遇します。この場合、中国語をエンコードする必要があります。UTF-8 に設定できます。デコード スキームは上記と同じです。 Postリクエストの場合、フォーム送信を「投稿」に設定した場合の送信方法です。次のように、Firefoxブラウザを介して特定のコンテンツを確認します。上の図では、post リクエストでは、リクエストの内容がリクエストボディに直接配置されて Web サーバーに送信され、エンコード方式が「utf-8」であることがわかります。 このレスポンスサーブレットでは、doPostメソッド本体は以下の通りです: ここでコードが文字化けする理由は、やはりコード getParameter ("user") を実行したときです。 Web サーバーはデフォルトのデコード スキーム「ISO-8859-1」を使用し、デコードされるため、エンコード スキームとデコード スキームの間に不一致が生じます。解決策としては、get リクエストの文字化け解決策を使用することもできますが、直接行うより簡単な解決策もあります。 /Decoding スキームが「utf-8」であることを指定します。計画は以下の通りです。以上でリクエストによるコード化けの解析は完了です。
レスポンスによって引き起こされるコード化けには、次の 4 つのメソッドを含める必要があります。 しかし、これら 2 つのメソッドは少し異なります。つまり、setHeader("Content-Type", "text/html;cahrset=utf-8") のメソッドでは、ブラウザは自動的に次のエンコーディング メソッドを使用します。デコードする応答本文。すべてのブラウザがこのメソッドのエンコーディング メソッドを使用して setCharacterEncoding() メソッドをデコードするわけではありません。以下で 2 つのメソッドをテストし、結果は次のとおりです。 りー 从上面可以看到第一个方法对于浏览器来说,支持的较好,提倡采用第一种方法设置响应体的字符编码方式。 对于获取响应字符输出流的方法,如果在此之前没有设置响应体的编码方式,那么默认为null,即ISO-8859-1方式进行编码。而且后面设置的编码方式会覆盖前面设置的编码方式。在getWriter()方法之后设置的编码无效。 对于获取响应输出字节流,我们在输出字符串时,我们需要设置字符串的编码方式如果没有那么默认ISO-8859-1。 对于前面2个输出流,由于只有一个输出缓存,所以这两个方法互斥。 以上,为了保证响应无乱码,需要保证字符编码和解码方法的统一,方案如下: 此外在Java web开发过程中,我们还会遇到当进行文件下载时,中文文件名导致的问题,如下图所示: 采用火狐浏览器进行测试,查看页面效果,及其响应结果如下: 经过查看响应头分析,下载文件名存放在响应头中,且对于中文文字没有采用UTF-8、UTF-16、GBK等等能识别中文的编码,那么对于中文文件名导致采用哪种编码方式呢?查看REF 7578得知,在此处采用ASCII编码,但是REF规定,如果不可避免的要使用非ASCII码的字符,程序员应该均匀的使用UTF-8,来最小化交互操作的问题。 所以,解决方案就是把文件名编码成UTF-8,传递给响应头,浏览器(部分)默认对该文件名进行UTF-8解码处理。 效果如下:其中火狐浏览器并没有对其解码 <a href="${pageContext.request.contextPath}/Test?user=<%=URLEncoder.encode("日向雏田", "UTF-8")%>">点击</a>
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user=request.getParameter("user");
System.out.println(user);//输出为æ¥åéç°
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 方案1
// response.setHeader("Content-Type", "text/html;charset=utf-8");
// response.getWriter().write("日向雏田");
// 方案2
// response.getOutputStream().write("日向雏田".getBytes("UTF-8"));
// 方案1,2互斥
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String realPath=this.getServletContext().getRealPath("/src/日向雏田.jpg");
String fileName=realPath.substring(realPath.lastIndexOf('\\')+1);
response.setHeader("content-disposition", "attachment;filename="+fileName);
InputStream is=new FileInputStream(new File(realPath));
OutputStream os=response.getOutputStream();
byte[] buff=new byte[1024];
int len=0;
while((len=is.read(buff))>0){
os.write(buff, 0, len);
}
os.close();
is.close();
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String realPath=this.getServletContext().getRealPath("/src/日向雏田.jpg");
String fileName=realPath.substring(realPath.lastIndexOf('\\')+1);
String utf_8Name=URLEncoder.encode(fileName,"utf-8");//解决方案
response.setHeader("content-disposition", "attachment;filename="+utf_8Name);
InputStream is=new FileInputStream(new File(realPath));
OutputStream os=response.getOutputStream();
byte[] buff=new byte[1024];
int len=0;
while((len=is.read(buff))>0){
os.write(buff, 0, len);
}
os.close();
is.close();
}
以上がJAVA WEB 注意事項 - 中国語文字化けの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。