1

我正在使用 Jersey 制作 RESTful 服务,它会生成 UTF-8 编码的回复。这是一个代码片段:

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]

请注意,欧元符号被编码为三个字节 -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。

我发现了一个导致这种损坏的转换序列,在某些时候 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。前者产生正确的 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 构建的,破坏了所有 Unicode 字符。

于 2013-02-06T15:05:56.763 回答
0

如果它在 7.0.30 而不是在 7.0.23 中工作,也许这是一个被发现并修复的错误?你检查过Tomcat 更新日志,看看里面是否有任何东西吗?

于 2013-02-06T12:56:33.637 回答