1

UTF-8 でエンコードされた応答を生成する Jersey を使用して RESTful サービスを作成しています。コード スニペットを次に示します。

public static class Data {

    private String value;

    public Data(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response method() {

    Data response = new Data("€");
    return Response.status(Response.Status.OK)
                   .type(MediaType.APPLICATION_JSON + ";charset=UTF-8")
                   .entity(response)
                   .build();
}

次の応答が生成されるはずです。

{"value":"€"}

またはバイト配列として:

[123, 34, 118, 97, 108, 117, 101, 34, 58, 34, -30, -126, -84, 34, 125]

ユーロ記号は 3 バイト -30、-126、-84 または0xe2 0x82 0xacとしてエンコードされることに注意してください。

ただし、次の応答が生成されます

{"value":"â¬"}

またはバイト配列として:

[123, 34, 118, 97, 108, 117, 101, 34, 58, 34, -61, -94, -62, -126, -62, -84, 34, 125]

現在、ユーロ記号は -61、-94、-62、-126、-62、-84 または 0xc3 0xa2 0xc2 0x82 0xc2 0xac の 6 バイトとしてエンコードされていることに注意してください。

UTF-8 でエンコードされたデータが、ある時点で Latin1 でエンコードされたデータとして扱われる、このような破損を引き起こす変換シーケンスを発見しました。

Data data = new Data("€");
org.codehaus.jackson.map.ObjectMapper mapper
    = new org.codehaus.jackson.map.ObjectMapper();
try {
    String strData = mapper.writeValueAsString(data);
    System.out.println(strData);
    byte[] rawData = mapper.writeValueAsBytes(data);
    System.out.println(Arrays.toString(rawData));

    String asLatin1 = new String(rawData, "ISO-8859-1");
    byte[] brokenUtf8 = asLatin1.getBytes("UTF-8");
    System.out.println(Arrays.toString(brokenUtf8));
} catch (IOException e) {
    System.out.println("Fail " + e.getMessage());
}

このサービスは、apache-tomcat-7.0.30 と apache-tomcat-7.0.23 の 2 台のマシンで実行されます。前者は正しい UTF-8 応答を生成しますが、後者は UTF-8 を破損しています。動作の違いの原因と問題の解決策を見つけることができません。

4

2 に答える 2

1

この問題には非常に悲しい理由があり、見つけるのが非常に困難でした。Ant の javac タスクには明示的なエンコーディング セットがありました。

<javac destdir="${classes}" includeantruntime="false" source="1.6" target="1.6" debug="true" encoding="ISO-8859-1" classpathref="main.classpath">

Tomcat は Eclipse で構築され、別のデプロイメントは Ant で構築されたため、1 つの Tomcat で動作していたため、すべての Unicode 文字が破損していました。

于 2013-02-06T15:05:56.763 に答える
0

7.0.23ではなく7.0.30で動作する場合、おそらくそれは発見され修正されたバグですか?Tomcatの変更ログをチェックして、そこに何かがあるかどうかを確認しましたか?

于 2013-02-06T12:56:33.637 に答える