【问题标题】:Sending UTF-8 string using HttpURLConnection使用 HttpURLConnection 发送 UTF-8 字符串
【发布时间】:2014-06-05 12:54:36
【问题描述】:

到目前为止,我使用以下代码 sn-p 来发送和接收 JSON 字符串:

static private String sendJson(String json,String url){
    HttpClient httpClient = new DefaultHttpClient();
    String responseString = "";
    try {
        HttpPost request = new HttpPost(url);
        StringEntity params =new StringEntity(json, "UTF-8");
        request.addHeader("content-type", "application/json");
        request.setEntity(params);
        HttpResponse response = httpClient.execute(request);
        HttpEntity entity = response.getEntity();
        responseString = EntityUtils.toString(entity, "UTF-8");

    }catch (Exception ex) {
        ex.printStackTrace();
        // handle exception here
    } finally {
        httpClient.getConnectionManager().shutdown();
    }
    return responseString;
}

即使 json 字符串包含 UTF-8 字符,上面的代码也能完美运行,并且一切正常。

出于多种原因,我不得不更改发送 HTTP 发布请求的方式并使用 HttpURLConnection 代替 apache 的 HttpClient。这是我的代码:

static private String sendJson(String json,String url){
    String responseString = "";
    try {
        URL m_url = new URL(url);
        HttpURLConnection conn = (HttpURLConnection)m_url.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("content-type", "application/json");
        DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream());
        outputStream.writeBytes(json);
        outputStream.flush();
        outputStream.close();

        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line+"\n");
        }
        br.close();
        responseString = sb.toString();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    return responseString;
}

此代码适用于普通英文字符,但似乎不支持 json 字符串中的 UTF-8 字符,因为它每次都失败。 (当向服务器发送 json 时,服务器崩溃说 utf8 无法解码某个字节,但是当从服务器接收 utf8 json 时,我认为它确实有效,因为我设法查看了特殊字符。

服务器根本没有改变,并且与以前的代码一起工作得很好,所以问题出在这个新代码 sn-p 上 100%。

知道如何修复 json 字符串发送以支持 UTF 8 吗?谢谢

【问题讨论】:

    标签: java android json httpurlconnection


    【解决方案1】:

    我认为问题出在这部分:

    DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream());
    outputStream.writeBytes(json);
    outputStream.flush();
    outputStream.close();
    

    您需要将 json 编码为 UTF-8,而不是这样做
    并发送那些代表 UTF-8 编码的字节。

    试试这个:

    Charset.forName("UTF-8").encode(json)
    

    见:

    Charset.encode

    一个更简单的方法是使用例如一个BufferedWriter 包装一个
    OutputStreamWriterOutputStreamWriter 知道自己的编码
    因此它将为您完成工作(json 字符串的编码工作)。

    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
    bw.write(json);
    bw.flush();
    bw.close();
    

    【讨论】:

      【解决方案2】:

      String 写入输出流(字节)时,您需要指定编码以进行转换。 一种方法是将输出流包装在OutputStreamWriter 中,该OutputStreamWriter 将使用UTF-8 字符集进行编码。

              conn.setRequestProperty("content-type", "application/json;  charset=utf-8");
              Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
              writer.write(json);
              writer.close();
      

      如果您调用close()flush() 也是可选的。

      另一个选项,正如 peter.petrov 所提到的,首先将您的 String 转换为字节(在内存中),然后将字节数组输出到您的输出流。

      为了在服务器端更明显,您可以传递内容类型标头中使用的字符集 ("content-type", "application/json; charset=utf-8")。

      【讨论】:

        【解决方案3】:

        StringEntity 使用Charset 来确保编码正确。它确实~那个:

        byte[] content = s.getBytes(charset);
        

        你的代码没有太大的变化,你的写作可以是:

        outputStream.write(json.getBytes("UTF-8"));
        

        就您的阅读而言,将BufferedReaderreadLine 一起使用是没有意义的,除了规范化行尾。它比其他方法慢得多,因为它需要单独读取每个字节。

        EntityUtils 主要是这样做的:

            Reader reader = new InputStreamReader(conn.getInputStream(), "UTF-8");
            StringBuilder buffer = new StringBuilder();
            char[] tmp = new char[1024];
            int l;
            while((l = reader.read(tmp)) != -1) {
                buffer.append(tmp, 0, l);
            }
            responseString = buffer.toString();
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-04
          • 2016-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多