杰西维Web服务JSON UTF-8编码

48

我使用Jersey 1.11创建了一个小的REST Web服务。当我调用返回JSON的URL时,非英文字符的字符编码出现问题。相应的XML URL(“test.xml”)在起始XML标记中使其成为utf-8。

我该如何使URL“test.json”返回UTF-8编码的响应?

以下是服务的代码:

@Stateless
@Path("/")
public class RestTest {   
    @EJB
    private MyDao myDao;

    @Path("test.xml/")
    @GET
    @Produces(MediaType.APPLICATION_XML )
    public List<Profile> getProfiles() {    
        return myDao.getProfilesForWeb();
    }

    @Path("test.json/")
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Profile> getProfilesAsJson() {
        return myDao.getProfilesForWeb();
    }
}

这是服务使用的POJO:

package se.kc.mimee.profile.model;

@XmlRootElement
public class Profile {
    public int id;
    public String name;

    public Profile(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Profile() {}

}

可能是如何使用JAX-RS设置字符集?的重复问题。 - rds
7个回答

102

Jersey应该默认始终生成utf-8,问题似乎是您的客户端没有正确解释它(xml声明并不能使其成为utf-8,只是告诉客户端如何解析它)。

您在哪个客户端看到这些问题?

有效的JSON只应该是Unicode(utf-8/16/32);解析器应该能够自动检测编码(当然,有些不行),因此JSON中没有编码声明。

您可以像下面这样将其添加到Content-Type中:

@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")

2
我在使用Chrome浏览器和谷歌的REST客户端时都遇到了问题,但是您的建议解决了这个问题 :) - Jojje
1
2015年了,我仍然有这个问题。 - Kalpesh Soni
我使用的是Jersey 1.19版本,我的输入为euzé de,但我的服务返回的是euzé de。我使用以下变量: @Produces(MediaType.TEXT_HTML+ ";charset=UTF-8")同时在客户端中也是这样设置:conn.setRequestProperty("Accept", "text/html"+ ";charset=UTF-8"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"+ ";charset=UTF-8"); - Somnath Kadam
1
亲爱的 @Dmitri,你的解决方案对于 @Produces 是有效的,但是对于 @Consumes 却无效。我该怎么办才能解决在输入参数中消耗字符串时出现的字符编码错误? - Hosein Aqajani

6

如果@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")无法正常工作,则尝试:

@Produces("application/json;charset=utf-8")

理论上来说是相同的,但第一种选项对我不起作用。


5

如果为每个资源都添加字符集不是选项,也许可以参考这个问题的答案来强制默认字符集。


5

responseMessage 是一个bean类,我们可以在响应中发送 UTF-8字符集

return Response.ok(responseMessage).header("Content-Type", "application/json;charset=UTF-8").build();

2

Jersey存在缺陷,当使用Content-Type应用程序/JSON时,它不会自动检测Unicode JSON编码,而是使用服务器运行时平台编码反序列化请求正文。响应正文序列化也是如此。

您的客户端需要明确指定UTF-8字符集:

Content-Type: application/json;charset=utf-8

0
你也可以尝试这个:
return Response.ok(responseMessage, "application/json;charset=UTF-8").build();

-1

我在servlet中遇到了同样的问题

请使用:resp.setContentType("application/json;charset=utf-8");

public static void flashOutput(HttpServletRequest req
            , HttpServletResponse resp
            , String output) {

        try {

            Utils.print2("output flash"+output);

            resp.setContentType("application/json;charset=utf-8");
            PrintWriter pw = resp.getWriter();
            pw.write( new String(output.getBytes("UTF-8")));
            pw.close();
            resp.flushBuffer();

        } catch (Exception e) {
            // TODO: handle exception
        }

    }// end flashOutput

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接