前几天帮助其他项目组做了一个API对接的项目,遇到了以下两个问题,在这里总结一下:
1.HttpPost请求参数中文乱码问题
2.Gson将json字符串转换为map,数值类型字段值改变
一、HttpPost请求参数中文乱码问题
项目中发送Post请求的工具方法如下:
public static String doPost(String requestUrl, Object param) throws IOException {
CloseableHttpClient httpClient = getHttpClient();
HttpPost post=new HttpPost(requestUrl);
post.setHeader("Content-Type","application/json;charset=UTF-8");
ObjectMapper mapper = new ObjectMapper();
String requestParam = mapper.writeValueAsString(param);
if(islog) {
System.out.println("这是请求参数:" + requestParam);
}
post.setEntity(new StringEntity(requestParam));
String responseString = httpClient.execute(post, response -> EntityUtils.toString(response.getEntity()));
if(islog) {
System.out.println("这是返回数据:" + responseString);
}
return responseString;
}
Debuge查看参数发送前的编码变化:
请求发出后:
进入StringEntity()方法,发现是个重载方法,如果不指定编码格式,则使用默认的ISO-8859-1的编码
所以将StringEntity所在行代码替换为
post.setEntity(new StringEntity(requestParam,"text/plain","UTF-8"));
指定UTF-8的编码,就不会出现中文乱码了。
二、Gson将json字符串转换为map,数值类型字段值改变
如上图所示,gson将json字符串转换为map后,数值类型的字段值发生了改变。
解决方式如下:
重新声明gson变量如下:
private static Gson gson = new GsonBuilder()
.registerTypeAdapter(
new TypeToken<TreeMap<String, Object>>(){}.getType(),
new JsonDeserializer<TreeMap<String, Object>>() {
@Override
public TreeMap<String, Object> deserialize(
JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
TreeMap<String, Object> treeMap = new TreeMap<>();
JsonObject jsonObject = json.getAsJsonObject();
Set<Map.Entry<String, JsonElement>> entrySet = jsonObject.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
Object ot = entry.getValue();
if(ot instanceof JsonPrimitive){
treeMap.put(entry.getKey(), ((JsonPrimitive) ot).getAsString());
}else{
treeMap.put(entry.getKey(), ot);
}
}
return treeMap;
}
}).create();
private static Type typeToken = new TypeToken<TreeMap<String, Object>>(){}.getType();
在需要进行json字符串和map转换的地方,按TreeMap<String, Object> result = gson.fromJson(json, typeToken);
此格式进行转换,就可以解决该问题。