目的
LibertyでもtWASと違いはありませんが、リクエストの文字コードを自動判別してデータを受け取る処理をテストします。
autoRequestEncoding と autoResponseEncoding
- Content-Type ヘッダー内の文字セットを見る。
- 定義されたプロパティーを使用してサーバーのロケールを文字セットにマップしようとする。
- DEFAULT_CLIENT_ENCODING システム・プロパティーを使用しようとする (設定されている場合)。
- ISO-8859-1 文字エンコード方式をデフォルトとして使用する。
文字コードの選択順についてはマニュアルに選択順はあるのですが、設定箇所についてがこれだけだと分かりにくいので、設定が必要な箇所について確認をします。
Webアプリケーションの設定
ibm-web-ext.xml に指定をします。設定内容の一覧を確認できるページもみつからないので、ここに残して置きます。auto-encode-requests と auto-encode-responses が指定できれば良いです。
<?xml version="1.0" encoding="UTF-8"?>
<web-ext
xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-ext_1_1.xsd"
version="1.1">
<default-error-page uri="error.html"/>
<reload-interval value="3"/>
<context-root uri="character-encoding"/>
<auto-encode-requests value="true"/>
<auto-encode-responses value="true"/>
<enable-directory-browsing value="false"/>
<enable-file-serving value="true"/>
<pre-compile-jsps value="true"/>
<enable-reloading value="true"/>
<enable-serving-servlets-by-class-name value="false" />
</web-ext>
上の設定は Eclipse の GUI で 以下を指定したものです。
Libertyサーバーのjvm.options
- DEFAULT_CLIENT_ENCODING システム・プロパティーを使用しようとする (設定されている場合)。
の指定をするのに jvm.options を記述します。
-Ddefault.client.encoding=Cp943C
自動選択で決定できなかった場合のデフォルト文字コードを指定できます。
コードに setCharacterEncoding(String encoding) メソッド
Servletでリクエストの文字コードを指定する方法です。この指定が最優先されます。
- DefaultServlet - setCharacterEncoding なし
- Ms932Servlet - setCharacterEncoding("MS932")
- Cp943CServlet - setCharacterEncoding("Cp943C")
で用意しました。DefaultServlet は request.getParameter("str") でパラメータを取得して文字コード出力する処理です。他のサーブレットはその処理の前に setCharacterEncoding をするようにしました。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String str = request.getParameter("str");
out.println("***** Original str : " + str + " *****");
str.codePoints().forEach(codePoint -> {
System.out.printf("Character %s, Code Point(HEX:16): U+%X%n",
Character.toString((char)codePoint), codePoint);
out.printf("Character %s, Code Point(HEX:16): U+%X%n",
Character.toString((char)codePoint), codePoint);
});
}
Cp943CServlet.java や Ms932Servlet.java は以下のようなコードです。
public class Cp943CServlet extends DefaultServlet {
...
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("Cp943C");
super.doGet(request, response);
}
}
Libertyテスト環境の自動構築
これまでの方法で既存環境に構成は可能ですが、環境をdockerで用意する方法です。
用意したGitレポジトリをクローンします。
git clone https://github.com/pdprof/character-encoding.git
cd character-encoding/character-encoding-docker/
Libertyのイメージをビルドして開始します。
./setup-docker.sh
./start.sh
起動したら以下にアクセスします。
str に 文字をPOSTしてテストするための curl コマンドが出力されます。
curl -v --data-binary "str=%81%5C" -H "Content-Type=application/x-www-form-urlencoded" localhost:9080/character-encoding/default
curl -v --data-binary "str=%81%5C" -H "Content-Type=application/x-www-form-urlencoded" localhost:9080/character-encoding/cp943
curl -v --data-binary "str=%81%5C" -H "Content-Type=application/x-www-form-urlencoded" localhost:9080/character-encoding/ms932
str パラメータをPOST
curl で str パラメータをポストします。ここでは入力した文字が期待した文字になるようにあらかじめ URLエンコードしたデータをPOSTします。
- --data-binary
- -H "Content-Type=application/x-www-form-urlencoded"
の引数が有効です。URLエンコードのデータについては文字コードを指定して期待したものにします。今回の例ではMS932, Cp943Cの文字コード指定でUnicode変換後の文字コードが変わる 0x815C を使用しました。
$ curl -v --data-binary "str=%81%5C" -H "Content-Type=application/x-www-form-urlencoded" localhost:9080/character-encoding/default
* Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> POST /character-encoding/default HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.76.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Servlet/3.1
< Content-Type: text/html; charset=ISO-8859-1
< Content-Language: en-US
< Transfer-Encoding: chunked
< Date: Sun, 31 Aug 2025 12:33:19 GMT
<
***** Original str : ? *****
Character ?, Code Point(HEX:16): U+2014
* Connection #0 to host localhost left intact
$ curl -v --data-binary "str=%81%5C" -H "Content-Type=application/x-www-form-urlencoded" localhost:9080/character-encoding/cp943
* Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> POST /character-encoding/cp943 HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.76.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Servlet/3.1
< Content-Type: text/html; charset=ISO-8859-1
< Content-Language: en-US
< Transfer-Encoding: chunked
< Date: Sun, 31 Aug 2025 12:33:44 GMT
<
***** Original str : ? *****
Character ?, Code Point(HEX:16): U+2014
* Connection #0 to host localhost left intact
$ curl -v --data-binary "str=%81%5C" -H "Content-Type=application/x-www-form-urlencoded" localhost:9080/character-encoding/ms932
* Trying 127.0.0.1:9080...
* Connected to localhost (127.0.0.1) port 9080 (#0)
> POST /character-encoding/ms932 HTTP/1.1
> Host: localhost:9080
> User-Agent: curl/7.76.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< X-Powered-By: Servlet/3.1
< Content-Type: text/html; charset=ISO-8859-1
< Content-Language: en-US
< Transfer-Encoding: chunked
< Date: Sun, 31 Aug 2025 12:33:58 GMT
<
***** Original str : ? *****
Character ?, Code Point(HEX:16): U+2015
* Connection #0 to host localhost left intact
default が、cp943 と同じコードポイントになっているのが分かります。jvm.options に指定した default.client.encoding=Cp943C の効果なので、これをMS932 に変えるなどして動作を検証します。
System Propertyの動的変更
で Set できるようにしたのですが、結果的にはサーバー再起動が必要で、指定は jvm.options が有効でした。
で指定されているのですが、static変数でクラスロード時に決定されてました。
トラブルシューティング
毎度のことですが、よくつかう dockerコマンドを書いておきます。この文書でもpodman, dockerとまとまりがないですが、Linux では dockerがpodmanを呼び出すようになっていました。
docker ps # 動作中のContainer確認
docker logs -f character-encoding # ログ確認
docker restart character-encoding # 再起動
docker inspectcharacter-encoding # container 確認
docker exec -it character-encoding bash # Container内状況確認
まとめ
Libertyでリクエストの文字コード自動判別処理をテストしました。

