3. Java Webの文字化けした問題の要約(詳細な説明)

1. response.getWriter()。write()とresponse.getWriter()。print()の違い

response.getWriter()は、印刷出力ストリームであるPrintWriterを返します。

response.getWriter()。write()とresponse.getWriter()。print()は、クライアントに応答するものです。データを受信して​​適切な場所に配置するためにajaxが必要ない場合は、新しいページブラウザで生成されます。コンテンツを表示します。

  1. print
    response.getWriter()。print()は、出力をテキスト形式(htmlタグを含む)で印刷できるだけでなく、オブジェクトをデフォルトのエンコーディングでバイナリバイト出力に変換することもできます。

  2. ライター
    response.getWriter()。writer()は、テキスト形式(htmlタグを含む)のみを印刷および出力でき、オブジェクトを印刷することできません。

2.一般的な文字化けした問題の分析

1.中国語がわかりにくい文字になります

漢字の文字列が「ÌÔ£¡ÎÒϲ»¶£¡」のように理解できない文字列になる場合、これは通常、エンコーディングです。

文字セットが、デコード時に使用される文字セットと矛盾しています。たとえば、GBKエンコーディングを使用する場合、ISO-8859-1デコーディングを使用する場合

結果はこんな感じ。

2.漢字が疑問符になります

エンコードとデコードの文字セットが同じである場合、文字エンコードは中国語をサポートしていないと判断できます(例:ISO-8859-1)。

3.漢字は2つの疑問符になります

中国語は複数回エンコードされており、エンコードまたはデコードの1つで中国語をサポートしていない文字セットが使用されています

3つの文字化けした関連知識ポイント:

1. UTF-8国際エンコーディング、GBK中国語エンコーディング。GBKにはGB2312が含まれています。つまり、GB2312でエンコードされている場合は、GBKでデコードできます。そうでない場合は、正しくない可能性があります。

2. Web Tomcat:デフォルトはISO8859-1で、中国語はサポートされていません

3.java.nio.charset.Charset.defaultCharset()プラットフォームのデフォルトの文字エンコードを取得します。

4. getBytes()は、プラットフォームのデフォルトの文字セットでエンコードされます。

5.コードテーブル:これは、私たちが理解する言語をコンピューターが理解できる言語に変換するために使用されるルールです。IS0-8859-1、GBK、UTF-8、UTF -16、および一連のメディアコードテーブルが多数あります。 GBK、UTF-8、UTF-16などのコードテーブルの多くは中国語の文字を識別でき、英語を識別したい場合は、IS0-8859-1などの他のコードテーブルを使用できます。

6.コーディング:私たちが理解できる言語をコンピューターが理解できる言語に変換します。このプロセスはコーディングの機能です

7.デコード:コンピューターで認識される言語を、理解できる言語に変換します。このプロセスはデコードの機能です

ブラウザは、httpプロトコルを介して送信されるUTF-8コードテーブルを使用します。httpプロトコルはIS0-8859-1のみをサポートします。サーバーに到着すると、デフォルトでIS0-8859-1コードテーブルも使用されます。写真は
ここに画像の説明を挿入します
3つのプロセスを示しています。、2つのエンコーディングを実行したため、2回デコードする必要があります。

1.ブラウザは「XiaoMing」をUTF-8コードテーブルでエンコードします(Xiao Mingは漢字であるため、中国語を識別できるコードテーブルを使用します。これはブラウザで手動で設定できるものでもあります。使用する場合、識別できません。中国語のコードテーブルでは、文字化けが発生します。中国語に対応するコンピュータシンボルがコードテーブルに見つからないため、???などの他のシンボルで表される可能性があります。コード化された結果は次のようになります。 1234、これはhttpプロトコルを介して送信されます。

2. HTTPプロトコル送信では、ISO-8859-1コードテーブルに示されているシンボルのみを使用できるため、元の1234を再度エンコードします。今回は、ISO-8859-1を使用して、何が取得されますか???、およびその後、サーバーに送信されます

3.サーバーによって取得されたデータはUTF-8でエンコードされ、TomcatサーバーはデフォルトでISO-8859-1デコードを使用します。エンコードとデコードに使用される文字セットに一貫性がないため、文字化けが発生します。

解決策:UTF-8でエンコードされたJSPページを使用してクライアントで要求を行う場合、ブラウザーでエンコードされたUTF-8バイトはISO-8859-1の形式でサーバーに渡されます。したがって、HTTPプロトコルを介して送信された元のバイトを取得するには、getBytes( "ISO-8859-1")を呼び出して元のバイトを取得する必要がありますが、クライアントの元のエンコーディングはUTF-8であるため、引き続き実行するとISO-8859 -1デコードの場合、結果は漢字ではなく、文字化けした3文字になります。したがって、クライアントの元の文字を復元するには、新しいString(bytes、 "UTF-8")を再度呼び出しバイト配列をUTF-8形式で3グループごとにデコードする必要があります。
???。getBytes( "ISO-8859-1"); //最初のデコード、コンピューターが認識できる言語への変換、
new String(1234、 "UTF-8"); // 2番目のデコード、変換私たちが知っている言語
ここに画像の説明を挿入します
ここに画像の説明を挿入します

サーブレットに関連する4つの文字化けしたコード

1.ブラウザがjsp、html、およびその他のページを呼び出して、中国語で文字化けした文字を表示します。
この種の文字化けした文字解決するには、次の2つの要件を満たす必要があります。

1)ファイル自体が編集されてutf-8に保存されます(myEclipseで、右クリックしてプロパティでutf-8を選択します)

2)ブラウザはutf-8を使用して以下を解析します。

(手動)==>ブラウザを右クリックして、エンコード形式をutf-8として選択します

(インテリジェント)==>次のようなファイルに書き込みます:タグを介して応答ヘッダーをシミュレートし、ブラウザーにutf-8エンコーディング分析を使用するように指示します

(スマート)==> response.setContentType( "text / html; charset = UTF-8"); utf-8エンコーディング分析を使用するようにブラウザーに指示します

一般的に使用される:

<meta name="content-type" content="text/html; charset=UTF-8">或<meta charset="utf-8">
<%@ pageEncoding="utf-8"%>
<?xml encoding="UTF-8"?>

2.ブラウザからサーブレットを呼び出すと、ページに文字化けが表示されます。
サーブレットの文字化けコードは、要求の文字化けコードと応答の文字化けコードに分けられます。

(1)これに応じて、ブラウザに表示される中国語の文字化け文字:

まず、応答オブジェクトがブラウザにデータを送信する方法を紹介します。2つのメソッド。1つはgetOutputStream、もう1つはgetWriterです。
1)ServletOutputStream getOutputStream(); //出力バイトストリームを取得します。write()とprint()の2つの出力メソッドを提供します

2)PrintWriter getWriter(); //出力文字ストリームを取得し、write()とprint()の2つの出力メソッドを提供します

print()メソッドの最下層はwrite()メソッドを使用します。これは、write()メソッドをカプセル化するprint()メソッドと同等であり、開発者がより便利かつ迅速に使用できるようにします。出力する場合、バイトの変換方法に関係なく、適切なprint()メソッド直接選択できます。
 1. ServeltOutputStream getOutputStream();中国語を直接出力できません中国語を直接出力すると例外が報告されます。
 ここに画像の説明を挿入します
解決策:
resp.getoutputStream()。write( "ははは、ブラウザーに出力したい" .getBytes( "UTF-8 "));
出力される漢字は、最初にtomcatではなくUTF-8でエンコードされるため、ブラウザーがUTF-8コードテーブルを使用してデコードすると、正しく出力されます。ブラウザーがUTF-8を使用していない場合、その後も文字化けしたコードが存在するため、これの鍵はブラウザが使用するコードテーブルによって異なります。これはあまり良くありません。ここで、もう1つの注意点があります。つまり、write(byte)メソッドが使用されます。 print()メソッドはバイトタイプMethodを出力しません

注:response.setContentTypeは、response.setCharacterEncoding + response.setHeaderと同等です。

解決:

方法1:response.setContentType( "text / html; charset = uft-8");

サーブレットAPIを使用してtomcaatに通知し、ブラウザにエンコードとデコードにUTF-8を使用するように強制します。この基本的なコードは、単純にカプセル化されたresponse.setCharacterEncoding + response.setHeaderのコードです。

/*
         通过设置响应头,来设置浏览器也使用UTF-8字符集 目的是为了控制浏览器的行为,即控制浏览器用UTF-8进行解码
         response.setContentType 等效于 response.setCharacterEncoding + response.setHeader
         因为在setContentType方法中已经调用了setCharacterEncoding方法设置了Response容器的编码了。
         注意:
              1.response.setContentType它会通是设置服务器和客户端都使用UTF-8字符集,
              2.还设置了响应头
              3.调用response.setCharacterEncoding 和  response.setContentType方法,
              必须在getWriter执行之前或者response被提交之前,否则依旧会出现乱码问题
         */
        response.setContentType("text/html;charset=UTF-8");

方法2:サーブレットAPIを使用するresponse.setCharacterEncoding( "UTF-8");

デフォルトのISO-8859-1を使用する代わりに、UTF-8を使用してブラウザーに応答する中国語をTomcatでエンコードします。これは、ブラウザーがUTF-8コードテーブルを使用するかどうかによって異なります。上記と同じです。に欠陥がある
ため、response.setHeader( "Content-Type"、 "text / html; charset = UTF-8");で使用する必要があります。これは、応答コンテンツを手動で設定し、Tomcatとブラウザーに使用を通知するために使用されます。 utf-8エンコードおよびデコードします。

/*
         response.setCharacterEncoding("UTF-8"):设置服务器的响应对象所采用的字符编码类型为UTF-8,即设置服务器字符集为UTF-8
         目的是用于解决response.getWriter()输出的字符流的乱码问题。
         */
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-Type","text/html;charset=UTF-8");

(setHeaderはHttpServletResponseのメソッドです。インターセプターFilterで文字エンコードを設定する場合、FilterのdoFilterメソッドのパラメータータイプはServletResponseであるため、そのようなメソッドはありません)

ここで注意すべきいくつかの小さな詳細があります:

  1. response.setCharacterEncoding( "UTF-8"); PrintWriter out = response.getWriter();の前に書き込む必要があります。文字ストリームを取得した後でエンコーディングを設定することは無意味です。

  2. response.setContentType( "text / html; charset = UTF-8");このコードには、実際には2つの関数があります。UTF-8で出力する応答を通知する機能と、UTF-8で開くようにブラウザーに通知する機能です。これは、response.setHeader( "content-type"、 "text / html; charset = UTF-8");およびresponse.setCharacterEncoding( "UTF-8"); 2文のコードと同等です。

  3. response.setContentType( "text / html; charset = UTF-8");目的は、ブラウザーの動作を制御すること、つまり、ブラウザーを制御してUTF-8でデコードすることです。

  4. response.setCharacterEncoding( "UTF-8");目的は、response.getWriter()出力文字ストリームの文字化けの問題を使用することです。response.getOutputStream()の場合、この文はUTF-8でデコードされたバイトストリームで応答オブジェクトのデータをブラウザーに送信することを意味するため、このソリューションは必要ありません。

(2)文字化けした問題をリクエストする

リクエストリクエストはpostとgetに分けられ、リクエスト方法ごとにコードが文字化けするさまざまな解決策があります

最初のタイプ:POSTリクエスト

postリクエストメソッドのパラメータはリクエスト本文にあり、getリクエストよりもはるかに単純です。httpプロトコルステップのエンコードプロセスを経ないため、サーバーによってデコードされたコードテーブルを設定するだけで済みます。サーバー側では、ブラウザーによってエンコードされたコードテーブルと同じになります。これで問題ありません。ここでは、ブラウザーはUTF-8コードテーブルエンコードを使用し、デコードに使用されるコードテーブルをサーバー側でUTF-8に設定しても問題ありません。 。
解決策:
request.setCharacterEncoding( "UTF-8"); //デフォルトのISO-8859-1の代わりにUTF-8コードテーブルデコードを使用するようにTomcatに命令します。
そのため、多くの場合、doPostメソッドの最初の文は、リクエストパラメータを取得するときに文字が文字化けするのを防ぐためのこのコードです。
注:この設定は、投稿リクエストにのみ有効です

2番目のタイプ:GET要求(URIモードでのパラメーターの送信が文字化けしている)、GETを使用したTOMCAT8.0以降では文字化けの問題はありません

getリクエストのパラメータはURLの後ろに送信されます。つまり、リクエスト行の
ここに画像の説明を挿入します
 FormServletは通常のサーブレットです。ブラウザがそれにアクセスすると、取得されたgetrequestメソッドを使用してname = Xiaomingのパラメータ値が送信されます。 doGetパラメータ値で、コンソールに出力され、文字化けしていることがわかりました

方法1:この問題を解決するには、Tomcatサーバーの構成ファイルを変更します。
[注] TOMCAT 8.0以降はGETメソッドで要求され、送信されるパラメーターはデフォルトでUTF-8で既にエンコードされているため、構成ファイルを変更する必要はありません。

tomcatディレクトリのconf / server.xmlファイルの69行目を変更します。

変更前のコンテンツ:

<Connector port="8080" protocol="HTTP/1.1"

     maxThreads="150"   connectionTimeout="200000"

     redirecPort="8443"/>

修改后内容:

 

<Connector port="8080" protocol="HTTP/1.1"

     maxThreads="150"   connectionTimeout="200000"

     redirecPort="8443"    URIEncoding="utf-8"/>

ここに画像の説明を挿入します

ここに画像の説明を挿入します

方法2:
String username = request.getParameter( "name");
String usernameString = new String(username.getBytes( "ISO-8859-1")、 "UTF-8");

TomcatはデフォルトでISO-8859を使用します-1エンコーディングは、ページがどのディスプレイを使用するかに関係なく、Tomcatは最終的にすべての文字をISO-8859-1に変換します。その後、別のターゲットページでGBK変換を使用すると、元々間違っていたエンコーディングがGBKに変換されます。テキストは文字化けします
。1.xxx.getBytes()はエンコーディングと呼ばれ、新しいString(byte []、encodingname)はデコーディングと呼ばれます。2。http
プロトコルはリクエストパラメータをエンコードまたはデコードしません。それは単なる送信であり、送信されるのはバイナリです。デコードはtomcatの仕事です。utf8でエンコードされたバイトシーケンスは、デフォルトでiso8895-1モードのtomcatでデコードされるため、コードが文字化けしているため、再エンコードしてデコードします。

a。最初に「文字」(それが何であれ)をバイト配列で表現する必要があります
。b。変換にISO-8859-1を使用し、ISO-8859-1エンコーディング環境でバイト配列を取得します。たとえば、 :ABは[64,65]として表されます
。c。次に、この配列をGBKでエンコードし、文字列に変換します。

次に、エンコード変換プロセスを取得できます。
仮定:GBKコード( "you")-> URLencodeは->(%3F%2F)-> Tomcatは自動的にISO-8859-1-> get(23 43 68 23 42 68各シンボルは、ISO-8859-1)->受信ページ-> ISO-8859-1のバイト配列に再度変換します[23,43,68,23,42,68]-> GBKを使用します。読み取り可能なテキストに変換するには—>(%3F%2F "----> to(" You ")

方法3:URL変換
String username = request.getParameter( "name");
String usernameString = new String(username.getBytes( "ISO-8859-1")、 "gb2312");

**
ブラウザーのデフォルトのエンコードはgb2312であるため

サマリーリクエストパラメータの文字化けの問題:

getリクエストとpostリクエストの中国語の文字化けした問題は異なる方法で処理されます

1)を取得:リクエストパラメータは、HTTPプロトコルを含む、リクエスト行にある手動で、文字化けの問題を解決する文字化けの原因を知っている、と右の薬を処方原理がすることです。。2つのエンコーディングと2つの復号プロセスを実行
新をString(xxx.getBytes( "ISO-8859-1")、 "UTF-8");

2)投稿:リクエスト本文で、サーブレットAPIを使用してリクエストパラメータの文字化けの問題を解決します。原則は、1回エンコードして1回デコードし、tomcatに特定のコードテーブルを使用してデコードするように命令することです。
request.setCharaterEncoding( "UTF-8");

五数要約

1)POSTリクエストの場合、これら2つの文を追加すると、基本的にすべての文字化けした問題を解決できます。

 response.setContentType("text/html;charset=UTF-8");
  request.setCharacterEncoding("UTF-8");

2)getリクエストの場合、TOMCAT 8.0以降はGETモードでリクエストされ、送信されるパラメータはデフォルトでUTF-8でエンコードされているため、getリクエストでコードの文字化けの問題は発生せず、必要ありません。構成ファイルを変更します

a。Tomcatサーバーの構成ファイルを変更した後、response.setContentType( "text / html; charset = UTF-8");を追加します。

b。構成ファイルを変更したくない場合は、次の方法を使用できます。

response.setContentType("text/html;charset=UTF-8");
String username= request.getParameter("name");
String usernameString = new String(username.getBytes("ISO-8859-1"),"UTF-8");



文字化けをリクエスト

1)リクエストを取得する:

2回エンコードされているため、2回デコードする必要があります

最初のデコード:xxx.getBytes( "ISO-8859-1"); get yyy

2番目のデコード:new String(yyy、 "utf-8");

連続書き込み:new String(xxx.getBytes( "ISO-8859-1")、 "UTF-8");

2)ポストリクエスト:

エンコードは1回だけなので、サーブレットAPI request.setCharacterEncoding();を使用して1回だけデコードする必要があります。

request.setCharacterEncoding("UTF-8");  
//不一定解决,取决于浏览器是用什么码表来编码,浏览器用UTF-8,那么这里就写UTF-8。

応答が文字化けしている

1)getOutputStream();
このバイト出力ストリームを使用すると、中国語を直接出力できず、例外が発生します。中国語を出力する場合の解決策は次のとおりです。

解決策:getOutputStream()。write(xxx.getBytes( "UTF-8")); //中国語をUTF-8コードテーブルで手動でエンコードし、送信用にバイトに変換します。バイトになった後、例外は報告されません。また、tomcatはエンコードされているためエンコードされません。したがって、ブラウザーの後で、ブラウザーがUTF-8コードテーブルのデコードを使用する場合、中国語の文字化けは発生しません。そうでない場合、中国語の文字化けが表示されるため、このメソッドはできません。中国語が文字化けしないことを完全に保証します

2)getWrite();
文字出力ストリーム使用して、例外なく中国語を直接出力しますが、文字化けした文字が表示されます。3つの方法で解決できます。常に2番目の方法を使用してください

解決策:同じコードテーブルを使用するようにTomcatとブラウザーに通知します。

response.setContentType( "text / html; charset = utf-8");  //ブラウザにUTF-8デコードを使用するように通知し、TomcatとブラウザにUTF-8エンコードとデコードを使用するように通知します。

このメソッドの基本原則は次の文です。response.setHeader( "contentType"、 "text / html; charset = utf-8");

注:2つのメソッドgetOutputStream()とgetWrite()を同時に使用することはできません。一度に使用できるのは、1つだけです。そうしないと、例外が報告されます。

おすすめ

転載: blog.csdn.net/weixin_44827418/article/details/110820714