Servlet日記(1999/03/07)

本日の成果

 昨日に引き続き、POSTした内容を、ファイルに保存する処理の実現についてです。

 フォームに半角英数文字を書いた場合は、うまくファイルに保存されるものの、全角文字を書くと、文字化けしていました。原因を調べるために、req.getParameter("uName")で得られる文字列を調べてみると、フォームに全角文字で書いた場合、シフトJISでエンコードされていることがわかりました。(もちろん、一般的にこうなるというわけではなく、今回の実行環境での話です。)

 以前、Servlet日記(1999/02/06)で日本語文字列の出力を試したときは、ソースコードをシフトJISで書くとうまくいったので、getParameter()メソッドがシフトJISでエンコードされた文字列を返すのは正しいかもしれないと考え、出力のエンコードもシフトJISになるよう指定してみましたが、やはりうまくいきません。

 Javaの入門書を読むと、文字列は内部的にはUnicodeで格納されている、というように書いてあるので、どう考えても、getParameter()メソッドの戻り値(シフトJISでエンコードされている)をそのまま使うのは、まずそうです。文字化けしたのは、println()メソッドが、引数がUnicodeでエンコードされているとみなして、デフォルトのエンコードタイプ(シフトJISか?)に変換したためではないかと思います。

 本来なら、入力文字列を、いったんシフトJISからUnicodeに変換するべきのように思いますが、ここでは大幅に手抜きして、write()メソッドを使って、そのままバイナリデータとしてファイルに書くようにしてみました。こうすればシフトJISでファイルに出力するので、一応、文字化けせずに動くようです。まっとうな対応は、将来の課題ということで・・・

 以上の変更の結果、doPost()メソッドは次のようになりました。

public void doPost(
    HttpServletRequest req,
    HttpServletResponse res
) throws ServletException, IOException
{
    PrintStream pwFile = new PrintStream(new BufferedOutputStream(new FileOutputStream("c:/saveFormData.txt")));
    pwFile.println(DateFormat.getDateTimeInstance().format(new Date()));
    writeLine(pwFile, req.getParameter("uName"));
    writeLine(pwFile, req.getParameter("uSubject"));
    writeLine(pwFile, req.getParameter("uContent"));
    pwFile.close();

    res.setContentType("text/plain");
    PrintWriter out = res.getWriter();
    out.print("ok");
}

private void writeLine(PrintStream ps, String s) {
    for (int i = 0; i < s.length(); i++)
        ps.write(s.charAt(i));
    ps.print("\n");
}

本日の教訓

 入力した文字列は、Unicodeでエンコードすべきではないか(まだ、よくわからない)。

Servlet日記(1999/03/06) Servlet日記の目次 Servlet日記(1999/03/14)