Java进行http发送数据,服务端接收为乱码

问题描述

Java使用HttpURLConnection进行http的post请求给服务器发送数据(用Java请求其他服务器,不是被请求的时候),服务器接收到数据为乱码,或有时候因为乱码而导致服务器无正确响应,请求的数据为json.toString(),包含中英文。 原代码:

URL url = new URL(url_api);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
con.setRequestProperty("Authorization", "Bearer " + get_token());
con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(json.toString());
out.flush();
out.close();
con.connect();

原因分析:

Java中writeBytes()的不完整介绍
Java中writeBytes()的不完整介绍

json.toString()得到的字符串为可变长度的UTF-8编码,即不同对于其中的汉字以3字节表示,而字母却同ASCII一样1字节表示;writeBytes()会丢弃汉字的多余字节,剩余的1字节服务器无法用UTF-8编码规则解码,导致乱码问题。

Java中writeUTF()的不完整介绍
Java中writeUTF()的不完整介绍

对此,DataOutputStream有UTF专用的writeUTF(),但蛋疼的是会先写入两字节表示后面写入的字节数,这两字节的存在服务器又无法解析。


解决方案:

Java中write(byte [])的介绍
Java中write(byte [])的介绍

一个办法是先将中英文字符串转化为byte[]字符串,再用write(byte [])方法写入,代码修改很简单,out.writeBytes(json.toString());改为out.write(json.toString().getBytes(StandardCharsets.UTF_8));即可。

修改后代码:

URL url = new URL(url_api);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
con.setRequestProperty("Authorization", "Bearer " + get_token());
con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.write(json.toString().getBytes(StandardCharsets.UTF_8));
out.flush();
out.close();
con.connect();
经验分享 程序员 微信小程序 职场和发展