如何在Java中更改HTTP响应中的字符集编码

8

我需要从远程服务器获取一些JSON对象,为此我使用了下面这个函数,它的工作非常好,只是有时会获取到一些奇怪的数据,我认为这是因为它使用ASCII字符集进行解码。

请查看下面我正在使用的方法:

public HttpResponse call(String serviceURL,String serviceHost,String namespace,String methodName,String payloadKey, String payloadValue) throws ClientProtocolException,IOException,JSONException
    {
            HttpResponse response = null;
            HttpContext HTTP_CONTEXT = new BasicHttpContext();
            HTTP_CONTEXT.setAttribute(CoreProtocolPNames.USER_AGENT, "Mozilla/5.0");
            HttpPost httppost = new HttpPost(serviceURL);
            httppost.setHeader("User-Agent",Constants.USER_AGENT_BROWSER_FIREFOX);
            httppost.setHeader("Accept", "application/json, text/javascript, */*");
            httppost.setHeader("Accept-Language","en-US,en;q=0.8");
            httppost.setHeader("Content-Encoding", "foo-1.0");
            httppost.setHeader("Content-Type", "application/json; charset=UTF-8");
            httppost.setHeader("X-Requested-With","XMLHttpRequest");
            httppost.setHeader("Host",serviceHost);
            httppost.setHeader("X-Foo-Target", String.format("%s.%s", namespace,methodName));
            /*Making Payload*/
            JSONObject objectForPayload = new JSONObject();
            objectForPayload.put(payloadKey, payloadValue);
            StringEntity stringentity = new StringEntity(objectForPayload.toString());
            httppost.setEntity(stringentity);
            response = client.execute(httppost);
            return response;


    }

我传递的所有标题都是正确的,并且通过在Google Chrome中检查元素或者在您熟悉的Mozilla的Firebug插件上验证了相同。

现在问题是,大多数情况下我得到可读数据,但有时我会得到不可读数据。

我使用eclipse进行了调试,发现wrappedEntity下的charset显示为"US-ASCII"。 我附上jpg供参考enter image description here

请问有人能告诉我在执行response = client.execute(httppost);之前如何将响应的字符集从ASCII更改为UTF-8。 PS:正如您已经注意到的,我在标头中传递了charset=utf-8,并且我已经使用firebug和google chrome验证了我正在传递确切的标头。

请放大图片以更清楚地看到图片

提前致谢

5个回答

11

我能够解决这个问题,只是希望为可能遇到类似问题的人提供帮助。 在获取响应后,首先使用以下代码获取实体:HttpEntity entity = response.getEntity(); 由于我的响应是一个JSON对象,因此需要将实体转换为字符串,但要使用“UTF-8”进行编码,就像这样:responseJsonObject = new JSONObject(EntityUtils.toString(entity,"UTF-8"));

之前,我只是使用以下代码:responseJsonObject = new JSONObject(EntityUtils.toString(entity));


1
我也遇到了同样的问题,IOUtils.toString(entity.getContent(), "UTF-8") 也无法正常工作。将其更改为 EntityUtils 就解决了问题。 - divillysausages

2

我认为问题不在于您的标题,而在于您的字符串。仅仅让标题显示utf-8并不能保证您编写的字符串是utf-8格式的,这取决于字符串的编码方式以及"payloadValue"中包含的内容。

话虽如此,您始终可以在发送之前正确地重新编码它,例如:

objectForPayload.put(payloadKey, payloadValue);
StringEntity stringentity = new StringEntity(
   new String(
      objectForPayload.toString().getBytes(),
      "UTF8"));

看看这是否对您有用。

感谢您的回复,但它并没有奏效。我很困惑,因为StringEntity只是我在有效载荷中传递的JSON对象,无论我是否对其进行UTF-8编码都不应该有影响。我认为我需要以某种方式更改响应的字符集编码,但我无法做到这一点。 - bourne

2
您可能需要添加一个“Accept-Encoding”头,并将其设置为“UTF-8”。

1
我尝试过了,但是没有起作用,结果相同:httppost.setHeader("Accept-Encoding","UTF-8"); - bourne
我使用 headers.put("Accept-Encoding", "UTF-8"); 成功了。 - Sanchi Girotra

1

仅供记录: "Content-Encoding" 头字段不正确 - 正确的服务器将拒绝请求,因为它包含未定义的内容编码格式。

此外,在 application/json 中附加字符集参数是没有意义的。


0

不过,Bourne在上面的评论中已经回答了这个问题。

entity = IOUtils.toString(response.getEntity().getContent())
改为 entity = EntityUtils.toString(response.getEntity(),"UTF-8")
就解决了问题。


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