1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Libertyでリクエストの文字コードを自動判別

Last updated at Posted at 2025-08-31

目的

LibertyでもtWASと違いはありませんが、リクエストの文字コードを自動判別してデータを受け取る処理をテストします。

autoRequestEncoding と autoResponseEncoding

  • Content-Type ヘッダー内の文字セットを見る。
  • 定義されたプロパティーを使用してサーバーのロケールを文字セットにマップしようとする。
  • DEFAULT_CLIENT_ENCODING システム・プロパティーを使用しようとする (設定されている場合)。
  • ISO-8859-1 文字エンコード方式をデフォルトとして使用する。

文字コードの選択順についてはマニュアルに選択順はあるのですが、設定箇所についてがこれだけだと分かりにくいので、設定が必要な箇所について確認をします。

Webアプリケーションの設定

ibm-web-ext.xml に指定をします。設定内容の一覧を確認できるページもみつからないので、ここに残して置きます。auto-encode-requests と auto-encode-responses が指定できれば良いです。

ibm-web-ext.xml
<?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 で 以下を指定したものです。

Screenshot from 2025-08-31 18-37-40.png

Libertyサーバーのjvm.options

  • DEFAULT_CLIENT_ENCODING システム・プロパティーを使用しようとする (設定されている場合)。

の指定をするのに jvm.options を記述します。

jvm.options
-Ddefault.client.encoding=Cp943C

自動選択で決定できなかった場合のデフォルト文字コードを指定できます。

コードに setCharacterEncoding(String encoding) メソッド

Servletでリクエストの文字コードを指定する方法です。この指定が最優先されます。

  • DefaultServlet - setCharacterEncoding なし
  • Ms932Servlet - setCharacterEncoding("MS932")
  • Cp943CServlet - setCharacterEncoding("Cp943C")

で用意しました。DefaultServlet は request.getParameter("str") でパラメータを取得して文字コード出力する処理です。他のサーブレットはその処理の前に setCharacterEncoding をするようにしました。

DefaultServlet.java
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 は以下のようなコードです。

Cp943CServlet.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

起動したら以下にアクセスします。

Screenshot from 2025-08-31 21-25-38.png

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の動的変更

Screenshot from 2025-08-31 21-25-38.png

で 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でリクエストの文字コード自動判別処理をテストしました。

1
0
1

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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?