Java 使用 HttpURLConnection 发送 UTF-8 字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24060787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sending UTF-8 string using HttpURLConnection
提问by Jjang
till now I've used the following code snippet in order to send and recieve JSON strings:
到目前为止,我已经使用以下代码片段来发送和接收 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;
}
The code above worked perfect even if the json string contained UTF-8 chars, and everything worked fine.
即使 json 字符串包含 UTF-8 字符,上面的代码也能正常工作,并且一切正常。
For several reasons I had to change the way I send HTTP post requests and use HttpURLConnection instead apache's HttpClient. Here's my code:
出于多种原因,我不得不改变发送 HTTP post 请求的方式,并使用 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;
}
This code works well for normal English characters, but doesn't seem to support UTF-8 characters in the json string, since it fails each time. (when sending json to server, server crushes saying that utf8 cant decode a certain byte, but when recieving utf8 json from server I think it does work since I manage to view the special characters).
此代码适用于普通英文字符,但似乎不支持 json 字符串中的 UTF-8 字符,因为它每次都失败。(当将 json 发送到服务器时,服务器崩溃说 utf8 无法解码某个字节,但是当从服务器接收 utf8 json 时,我认为它确实有效,因为我设法查看了特殊字符)。
Server didn't change at all and worked fine with previous code, so the problem is 100% on this new code snippet.
服务器根本没有改变并且与以前的代码一起工作得很好,所以这个新代码片段的问题是 100%。
Any idea how to fix the json string sending so it would support UTF 8? Thanks
知道如何修复 json 字符串发送以支持 UTF 8 吗?谢谢
采纳答案by peter.petrov
I think the problem is in this part:
我认为问题出在这一部分:
DataOutputStream outputStream = new DataOutputStream(conn.getOutputStream());
outputStream.writeBytes(json);
outputStream.flush();
outputStream.close();
Instead of doing this you need to encode json as UTF-8
and send those bytes which represent the UTF-8 encoding.
您需要将 json 编码为 UTF-8
并发送那些代表 UTF-8 编码的字节,而不是这样做。
Try using this:
尝试使用这个:
Charset.forName("UTF-8").encode(json)
See:
看:
An even simpler approach is to use e.g. a BufferedWriter
wrapping anOutputStreamWriter
. The OutputStreamWriter
knows about its own encoding
and so it will do the work for you (the encoding work of the json
String).
一种更简单的方法是使用例如BufferedWriter
包装一个OutputStreamWriter
. TheOutputStreamWriter
知道它自己的编码
,因此它将为您完成工作(json
String的编码工作)。
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
bw.write(json);
bw.flush();
bw.close();
回答by Fradenger
When writing a String
to an output stream (bytes), you need to specify the encoding to do the conversion.
One way to do is to wrap the output stream in a OutputStreamWriter
that will use UTF-8 charset for the encoding.
将 a 写入String
输出流(字节)时,您需要指定编码以进行转换。一种方法是将输出流包装在OutputStreamWriter
将使用 UTF-8 字符集进行编码的 a 中。
conn.setRequestProperty("content-type", "application/json; charset=utf-8");
Writer writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
writer.write(json);
writer.close();
The flush()
is also optional if you call close()
.
的flush()
,如果你打电话也是可选的close()
。
Another option, as mentionned by peter.petrovis to first convert your String
to bytes (in memory) and then output the byte array to your output stream.
另一种选择,正如peter.petrov所提到的,首先将您String
的字节转换为字节(在内存中),然后将字节数组输出到您的输出流。
And to make it obvious on the server side, you can pass the charset used in the content-type header ("content-type", "application/json; charset=utf-8"
).
为了在服务器端显而易见,您可以传递在内容类型标头 ( "content-type", "application/json; charset=utf-8"
) 中使用的字符集。
回答by njzk2
StringEntity
uses a Charset
to make sure the encoding is right. It does ~that:
StringEntity
使用 aCharset
来确保编码正确。它确实〜:
byte[] content = s.getBytes(charset);
Without much change in your code, your write can be:
无需对代码进行太多更改,您的编写可以是:
outputStream.write(json.getBytes("UTF-8"));
As for your read, there is no point in using a BufferedReader
with readLine
, except for normalizing the end of line. It is much slower than other methods, as it requires to read each byte individually.
至于您的阅读,除了规范化行尾之外,使用BufferedReader
with没有任何意义readLine
。它比其他方法慢得多,因为它需要单独读取每个字节。
EntityUtils
does mostly that:
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();