5
1

More than 1 year has passed since last update.

java基礎:java文字化けと解決のまとめ

Last updated at Posted at 2023-07-27

最近、たまに仕事に文字化けの現象が発生しましたので、javaの文字化けを整理してみます。

コンパイル不備の文字化け

例1:

単純なjavaサンプルですが、保存時の文字コードの設定を出力結果への影響を試します。

public class helloTokyo{
	public static void main(String[] args){
		System.out.println("hello tokyo");
		System.out.println("hello東京");
	}
}

まず、MS932で保存してコンパイルしてテストします。
image.png
文字化けなし。
image.png
次は、UTF-8で保存してコンパイルしてテストします。
image.png
見事に文字化けしています!
image.png
javacのコンパイルする際、デフォルト文字コードはOSにより変わります。日本語windowsの場合MS932です。ソースはjavacのデフォルト文字コードと一致する場合、出力は正しいです。
ただし、UTF-8でプログラムするなということではないです。以下のようにjavacのencodingパラメータを指定すれば、文字化けがなくなります!
image.png

例2:

次はjspサンプルで試験をやります。1行目のpageEncodingはコンパイル時jspファイルをどう読み込むかかの設定と理解すればよいです。contentTypeはサーバからブラウザーへ送信時の文字コードです。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="MS932"%>
<!DOCTYPE HTML>
<HTML>
<BODY>
hello Tokyo<br>
hello 東京<br>
</BODY>
</HTML>

MS932のままで保存して実行します。文字化けなし。
image.png
次はUTF-8で保存して実行します。文字化け発見!
image.png

ソースの1行目を以下のように、pageEncodingをUTF-8に修正したら、文字化けが解消です。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="UTF-8"%>

image.png

POST送信の文字化け

WEB送信はよくPOST方法でやります。送信内容をサーバ側から受け取るとき文字化けだったら困ります。

例3:

前述の例を改修してPOST送信と送信内容表示機能を付けます。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<HTML>
<BODY>
hello Tokyo<br>
hello <%=request.getParameter("txt")%><br>
<form method="post">
<input name="txt" value="東京">
<input type=submit value="送信">
</form>
</BODY>
</HTML>

送信ボタンを押します。文字化け発見!
image.png
開発者ツールで送信内容を取得してオンラインDecodeしてみましょう。
image.png
MS932(ShiftJISの拡張)の文字はURLエンコードディングされているとわかりました。
image.png
そしてrequestの文字コードをMS932で指定すれば問題解決です。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<HTML>
<BODY>
<%
	request.setCharacterEncoding("MS932");
%>
hello Tokyo<br>
hello <%=request.getParameter("txt")%><br>
<form method="post">
<input name="txt" value="東京">
<input type=submit value="送信">
</form>
</BODY>
</HTML>

image.png

自分から自分へPOST送信するときjspのcontentTypeとrequestの文字コード指定を統一すれば問題なしと結論しやすいですね。正しいかどうか次の段落をみてください。

例4:

もしPOST送信先は別システムのもので向こうのrequest文字コードを編集できない場合どうすればいいですか。この場合、自分のformの文字コードaccept-charsetを指定しましょう。前述の例と区別するため、今回は、formとrequestの文字コードを全部UTF-8にします。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<HTML>
<BODY>
<%
	request.setCharacterEncoding("UTF-8");
%>
hello Tokyo<br>
hello <%=request.getParameter("txt")%><br>
<form method="post" accept-charset="UTF-8">
<input name="txt" value="東京">
<input type=submit value="送信">
</form>
</BODY>
</HTML>

image.png
結論:POSTの場合、送信文字コード指定request setCharacterEncodingこの2箇所が同じであれば文字化けなしです。別々だったら文字化けです。
formのaccept-charsetがあれば、それは送信の文字コード指定になります。formのaccept-charsetがなければ、jsp画面ロード時のcontentTypeの文字コードはデフォルトの送信文字コードになります。

GET送信の文字化け

GETは送信内容をURL経由でサーバに渡します。基本的に英数字のコードの送信を推奨されますが、たまに名称とかメッセージとかを送信してみたら、大抵ひどい目になりますね。

例5:

以下のようになもにしないままで、get方法の送信内容を取得してみます。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<HTML>
<BODY>
<%
	String txt=request.getParameter("txt");
%>
hello Tokyo<br>
hello <%=txt%><br>
<form method="get">
<input name="txt" value="東京">
<input type=submit value="送信">
</form>
</BODY>
</HTML>

文字化け発見!
image.png
POSTと違って送信後のURLは長くなります。

http://localhost:8080/helloworld/helloTokyo.jsp?txt=%93%8C%8B%9E

また開発者ツールで閲覧する場合、MS932のエンコードとわかります。つまりcontentTypeと同じMS932です。
image.png

GET方法は、setCharacterEncodingが効かないです。話によるとtomcatの設定を変更すればsetCharacterEncodingを有効にさせることですが、好みではありません。参考までやり方を貼り付けます。

<Connector port="8080" maxHttpHeaderSize="8192"
           maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
           enableLookups="false" redirectPort="8443" acceptCount="100"
           connectionTimeout="20000" disableUploadTimeout="true" 
 useBodyEncodingForURI="true"/>

プログラムの対応方法は以下です。

<%@ page language="java" contentType="text/html; charset=MS932"
 pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<HTML>
<BODY>
<%
	String txt=request.getParameter("txt");
	if (txt!=null){
		txt=new String(txt.getBytes("ISO-8859-1"),"MS932");
	}
%>
hello Tokyo<br>
hello <%=txt%><br>
<form method="get">
<input name="txt" value="東京">
<input type=submit value="送信">
</form>
</BODY>
</HTML>

image.png
結論:ISO-8859-1はjavaの内部文字コードです。requestからのGET送信内容をISO-8859-1でバイト配列を作成して、送信時文字コードで文字列を再作成するということです。

tomcatコンソールの文字化け

zip版のtomcatを実行する場合、コンソール画面が文字化けです。
image.png
これは、logging.propertiesの設定による現象です。tomcatの各種設定はデフォルトとしてlinux向けです。そして、logging.propertiesに設定される文字コードもlinux向けでUTF-8にされています。windowsのデフォルト文字コードはMS932なので合わないから文字化けです。対応方法は以下のように、コンソールに出力する文字コードをMS932にすることです。
image.png
これで文字化け解決。
image.png

5
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
1