解决使用httpclient传递json数据乱码的问题
今天用httpclient传输json数据,服务端接受数据 中文乱码,下面分别贴上修改前与修改后的代码以及原因分析
(1)修改前:
client端
public String sendHttpPost(String httpUrl, String data) { // 创建post请求 HttpPost httpPost = new HttpPost(httpUrl); StringEntity entity; try { entity = new StringEntity(data); entity.setContentEncoding("UTF-8"); entity.setContentType("application/json"); httpPost.setEntity(entity); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return sendHttpPost(httpPost); }
private String sendHttpPost(HttpPost httpPost) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; // 创建默认的httpclient实例 httpClient = HttpClients.createDefault(); httpPost.setConfig(requestConfig); httpPost.setHeader("Accept","aplication/json"); httpPost.addHeader("Content-Type","application/json;charset=UTF-8"); // 执行请求 try { logger.info("开始同步数据"); response = httpClient.execute(httpPost); entity = response.getEntity(); responseContent = EntityUtils.toString(entity, "UTF-8"); logger.info("数据同步结果:" + responseContent); } catch (IOException e) { logger.error("同步数据出错:" + e.toString()); e.printStackTrace(); } finally { try { if (response != null) { response.close(); } if (httpClient != null) { httpClient.close(); } } catch (Exception e2) { logger.error("流关闭出错:" + e2.toString()); } } return responseContent; }
(2)修改后
client端
public String sendHttpPost(String httpUrl, String data) { // 创建post请求 HttpPost httpPost = new HttpPost(httpUrl); StringEntity entity; entity = new StringEntity(data,"UTF-8"); entity.setContentType("application/json"); //entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));//用这个跟上面一行那个结果一样,可以查看源码 httpPost.setEntity(entity); return sendHttpPost(httpPost); } private String sendHttpPost(HttpPost httpPost) { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; HttpEntity entity = null; String responseContent = null; // 创建默认的httpclient实例 httpClient = HttpClients.createDefault(); httpPost.setConfig(requestConfig); httpPost.setHeader("Accept","aplication/json"); httpPost.addHeader("Content-Type","application/json;charset=UTF-8"); }
服务端 代码
//服务端 代码 通过红色字体的代码接受数据 public Map<String, Object> getRequestPostParams(HttpServletRequest request) throws BusinessException { try { //接收数据 StringBuffer sb = new StringBuffer() ; InputStream is = request.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "utf-8"); BufferedReader br = new BufferedReader(isr); String s = "" ; while((s=br.readLine())!=null){ sb.append(s) ; } String strData = sb.toString(); if (null == strData || "".equals(strData)) { return new HashMap<String, Object>(); } Map<String, Object> params = this.parseJSON2Map(strData); return params; } catch(Exception e) { throw new BusinessException(BusinessException.ERROR_INNER, "参数转换错误!"); } }
下面来解释原因:
看到这里 发现了client端的不同的吧,没错 只有一行代码不一样
entity = new StringEntity(data,"UTF-8");
就是这行代码,因为构造方法的不同造成的
本来参考了这篇文章把问题解决了,但是我发现 我自己的代码明明也设置额编码 为什么会出现乱码呢,于是我就去看源代码的实现,差异在哪里? 下面贴上源代码
public StringEntity(final String string, final ContentType contentType) throws UnsupportedCharsetException { super(); Args.notNull(string, "Source string"); Charset charset = contentType != null ? contentType.getCharset() : null; if (charset == null) { charset = HTTP.DEF_CONTENT_CHARSET; } try { this.content = string.getBytes(charset.name()); } catch (final UnsupportedEncodingException ex) { // should never happen throw new UnsupportedCharsetException(charset.name()); } if (contentType != null) { setContentType(contentType.toString()); } }
然后就发现,在new StringEntity的时候,就已经将数据根据编码进行了处理,也就是说,如果你调用 new StringEntity(String string)此构造方法,就会使用其默认的编码进行转码(ISO-8859-1),无论你后面设置多少次(
entity.setContentEncoding("UTF-8");
或者
httpPost.addHeader("Content-Type","application/json;charset=UTF-8");
都不会改变字符串已经被按转码变成Byte[]数组的事实,当然在请求中设定传输编码格式还是要做的。
其实说这么多 ,解决问题的关键就一句话,在new StringEntity()的时候指定编码就解决了,因为在new的同时已经做了字符串的转码操作
之所以说这么多,是想告诉自己,问题解决了固然是好,但应该知道为什么这么做,多看源码,多问自己为什么,仅此共勉。
补充:httpclient post发送json数组并解决json乱码问题
业务:
客户端发送json数据,服务端进行解析
client发送json格式:
{"data":[{"name":"1;,a","id_no":"222,a","cellphone":"123141a","abode_detail":"213,a","emp_add":"werew3a","app_no":"111111111111a","create_time":"11a"},{"name":"张三","id_no":"null","cellphone":"null","abode_detail":"null","emp_add":"null","app_no":"null","create_time":"null"},{"name":"1;,","id_no":"222,","cellphone":"123141","abode_detail":"213,","emp_add":"werew3","app_no":"111111111111","create_time":"11"},{"name":"1;,ab","id_no":"222,ab","cellphone":"123141ab","abode_detail":"213,ab","emp_add":"werew3ab","app_no":"111111111111ab","create_time":"11ab"}],"sendtime":"20160503"}
废话少说,直接上主要代码
client端
package msxf.until; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import msxf.until.model.People; import org.apache.http.HttpStatus; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.methods.RequestBuilder; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by 小省. */ public class Main { private final static org.apache.log4j.Logger logger =org.apache.log4j.Logger.getLogger(Main.class); public static void main(String[] args) { Map ma=new HashMap(); ma.put("sendtime","20160503"); //连接impala查库,返回List<People>,其中peopel为自定义实体类 List<People> peopleList=ImpalaJdbc.connImpala(); if(peopleList.size()==0){ logger.info("peopleList.size()==0"); } ma.put("data",peopleList); ObjectMapper om=new ObjectMapper(); try { String jsonStr=om.writeValueAsString(ma); System.out.println(jsonStr); CloseableHttpResponse httpResponse=null; CloseableHttpClient httpClient= HttpClientBuilder.create().setRetryHandler(new DefaultHttpRequestRetryHandler()).build(); //解决中文乱码,注意与服务端同时存在 StringEntity stringEntity=new StringEntity(jsonStr,"UTF-8"); //就目前来说下面这段代码是可有可无 stringEntity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); //post 地址 HttpUriRequest httpUriRequest= RequestBuilder.post("http://localhost:8080/qc").setEntity(stringEntity).build(); httpResponse=httpClient.execute(httpUriRequest); System.out.println("发送"); int statusCode=httpResponse.getStatusLine().getStatusCode(); if(statusCode== HttpStatus.SC_OK){ // HttpEntity entity = httpResponse.getEntity(); // InputStream in =entity.getContent(); System.out.println("文件传输服务器正常响应!"); } } catch (JsonProcessingException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
服务端
采用最原始的servlet
import org.apache.http.protocol.HTTP; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URLDecoder; /** * Created by 小省. */ public class QcServlet extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { doGet(request,response); } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { System.out.println("+++++++++++++++++++"); //解决中文乱码 BufferedReader br =new BufferedReader(new InputStreamReader(request.getInputStream(),"UTF-8")); String line=null; StringBuffer sb =new StringBuffer(); while ((line=br.readLine())!=null){ sb.append(line); } System.out.println("sb.toString()"+sb.toString()); //就目前而言String reesult = URLDecoder.decode(sb.toString(), HTTP.UTF_8);是可有可无的,httpclient会自动解码 //String reesult =sb.toString(); String reesult = URLDecoder.decode(sb.toString(), HTTP.UTF_8); try { //将string 字符串转化为json数组,并且遍历 JSONObject jsonObject =new JSONObject(reesult); String mesage=(String) jsonObject.getString("data"); JSONArray myJsonArray = new JSONArray(mesage); for(int i=0 ; i < myJsonArray.length() ;i++){ //获取每一个JsonObject对象 JSONObject myjObject = myJsonArray.getJSONObject(i); System.out.println(myjObject.getString("name")); } System.out.println(reesult); } catch (JSONException e) { e.printStackTrace(); } } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。如有错误或未考虑完全的地方,望不吝赐教。
相关文章
- 最近做了个扫描二维码得到vcard的项目,遇到一个问题,有一部分生成完的二维码,用android系统手机扫描后得到的vcard中的中文姓名是乱码,经过比对发现,这部分vcard中ORG这个...2016-11-25
- 这篇文章主要介绍了gin 获取post请求的json body操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-15
- 新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
- JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。JSON采用完全独立于语言的文本格式,这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成...2021-11-05
C#使用Http Post方式传递Json数据字符串调用Web Service
这篇文章主要为大家详细介绍了C#使用Http Post方式传递Json数据字符串调用Web Service,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-06-25- 今天在写一个vbs的时候,发现中文乱码,后来写好代码正常运行的代码压缩一下给了同事,发现报无效字符,经过验证后发现原来是编码的问题导致,这里就为大家分享一下...2020-06-30
- 下面小编就为大家带来一篇js遍历json的key和value的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-01-26
关于Mysql中文乱码问题该如何解决(乱码问题完美解决方案)
最近两天做项目总是被乱码问题困扰着,这不刚把mysql中文乱码问题解决了,下面小编把我的解决方案分享给大家,供大家参考,也方便以后自己查阅。首先:用show variables like “%colla%”;show varables like “%char%”;这两条...2015-11-24- 这篇文章主要介绍了C#读取中文文件出现乱码的解决方法,涉及C#中文编码的操作技巧,非常具有实用价值,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了详解.NET Core 3.0 里新的JSON API,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22
- 在 php 中使用 json_encode() 内置函数(php > 5.2)可以使用得 php 中数据可以与其它语言很好的传递并且使用它。这个函数的功能是将数值转换成json数据存储格式。<?php$arr = array ( 'Name'=>'希亚', 'Age'...2015-11-08
ASP.NET Core根据环境变量支持多个 appsettings.json配置文件
这篇文章主要介绍了ASP.NET Core根据环境变量支持多个 appsettings.json配置文件,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-09-22基于Vue+Openlayer实现动态加载geojson的方法
本文通过实例代码给大家介绍基于Vue+Openlayer实现动态加载geojson的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...2021-09-01- 这篇文章主要介绍了Java连接数据库oracle中文乱码解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-16
- 下面就为大家带来一篇jquery对Json的各种遍历方法总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2016-10-02
解决HttpPost+json请求---服务器中文乱码及其他问题
这篇文章主要介绍了解决HttpPost+json请求---服务器中文乱码及其他问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-22- 本文给大家介绍如何替换json对象中的key,通过实例代码给大家介绍key的替换方法,代码也很简单,需要的朋友参考下吧...2021-06-02
C#中HttpWebRequest、WebClient、HttpClient的使用详解
这篇文章主要介绍了C#中HttpWebRequest、WebClient、HttpClient的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25JSON字符串转换JSONObject和JSONArray的方法
这篇文章主要介绍了JSON字符串转换JSONObject和JSONArray的方法的相关资料,需要的朋友可以参考下...2016-06-12- 用到iconv函数把抓取来过的utf-8编码的页面转成gb2312, 发现只有用iconv函数把抓取过来的数据一转码数据就会无缘无故的少一些 代码如下 复制代码 ...2016-11-25