解决使用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();
}
}
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • java 利用HttpClient PostMethod提交json数据操作

    故事前要 今天,在做公司的一个项目,需要和第三方公司进行对接,需要将我们采集到的数据发送给第三方公司,按照对方提供的文档,传递好参数后,httpclient.execute(method)请求后,得到的状态码 ,一直是502,犹豫第一次使用HttpClient post json数据,一直怀疑是自己的代码问题,最后不知在哪个技术论坛看到 ,有人问url请求中有空格怎么办,突然发现对方提供的pdf文档中 竟然包含空格,而我天真的无视掉了 以为是文档的问题. 算了-- 不多BB了-. PostMet

  • java HttpClient传输json格式的参数实例讲解

    最近的一个接口项目,传的参数要求是json,需要特殊处理一下. 重点是这两句话: httpPost.setHeader("Content-Type", "application/json;charset=UTF-8"); se.setContentType(CONTENT_TYPE_TEXT_JSON); 这两句话的作用与jmeter的设置header信息类似 package com.base; import java.io.UnsupportedEncodingE

  • httpclient 请求http数据,json转map的实例

    实例如下: package com.idc.dataAudit.dataResource; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import net.sf.json.JSONArray; import net.sf.json.JSONObject; import org.apache

  • httpclient模拟post请求json封装表单数据的实现方法

    废话不说上代码: public static String httpPostWithJSON(String url) throws Exception { HttpPost httpPost = new HttpPost(url); CloseableHttpClient client = HttpClients.createDefault(); String respContent = null; // json方式 JSONObject jsonParam = new JSONObject(

  • 解决使用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); ent

  • 解决Ajax加载JSon数据中文乱码问题

    一.问题描述 使用zTree的异步刷新父级菜单时,服务器返回中文乱码,但项目中使用了SpringMvc,已经对中文乱码处理,为什么还会出现呢? 此处为的异步请求的配置: Java代码 async: { enable: true, url: basePath + '/sysMenu/listSysMenu', autoParam: ["id=parentId"] } SpringMvc中文字符处理: Java代码 <mvc:annotation-driven> <mvc

  • SpringBoot响应Json数据乱码通过配置的解决

    目录 场景 实现 把SpringBoot的response编码设置为utf-8 找到application.properties配置文件 添加如下: #设置响应为utf-8spring.http.encoding.force-response=true 再次刷新浏览器 SpringBoot返回json数据乱码 第一种解决方式 在请求RequestMapping直接设置,只针对请求,在拦截器返回json数据时有可能乱码 @RequestMapping(value ="/user", pr

  • Android中post请求传递json数据给服务端的实例

    在最近的项目中有个需求是这样的: 入参封装成JSON,EXAMPLE: { "uuid": "iamauuid", "clientType": "AND", "content": "{\"gender\":\"F\",\"name\":\"TTT\"}"} 其中content中是json的object,且要求

  • 使用easyui从servlet传递json数据到前端页面的两种方法

    两种方法获取的数据在servlet层传递的方法相同,下面为Servlet中代码,以查询表中所有信息为例. //重写doGet方法 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub ​ request.setCharacterEncoding("

  • php基于jquery的ajax技术传递json数据简单实例

    本文实例讲述了php基于jquery的ajax技术传递json数据简单实现方法.分享给大家供大家参考,具体如下: html页面: <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <script type="text/javascript" src="jquery-1.8.2.mi

  • 解决spring mvc 返回json数据到ajax报错parseerror问题

    最近使用ajax接收spring mvc传过来的json数据时总是出现parseerror的错误,错误源码如下: 前端: $.ajax({ type: 'POST', url: "groupFunctionEdit", dataType: 'json', contentType: "application/json", data: JSON.stringify(functiondata), success: function(data){ alert('数据加载成功

  • Java Http请求传json数据乱码问题的解决

    业务场景:调easyui的dialog打开一个弹窗,传参是用json封装的,而且有中文,然后在极速模式是正常的,在ie11测试发现中文出现乱码了 var params = JSON.stringify(writParamList); top.dialog({ id: 'noticeList', title:'列表', width:900, height:500, url:'${root}/notice/multiNoticeList.do?params='+params, onclose:fun

  • C#使用Http Post方式传递Json数据字符串调用Web Service

    引言 前段时间一直在做一个ERP系统,随着系统功能的完善,客户端(CS模式)变得越来越臃肿.现在想将业务逻辑层以下部分和界面层分离,使用Web Service来做.由于C#中通过直接添加引用的方来调用Web Service的方式不够灵活,故采取手动发送Http请求的方式来调用Web Service.最后选择使用Post方式来调用Web Service,至于安全性和效率暂不考虑.在学习使用的过程,遇到了很多问题,也花了很长时间来解决,网上相关的帖子很少,如果各位在使用的过程中有一些问题难以解决,可

  • 解决SpringMvc后台接收json数据中文乱码问题的几种方法

    1.使用ajax从前台页面传输数据到后台controller控制器的时候,出现中文乱码(问号???). 之前在网上找了各种解决方案,都行不通,最后发现是tomcat服务器接收数据的问题 解决方案: 方式一:在controller接收参数时,对参数进行转码 @ResponseBody @RequestMapping(value="/getJsonDataByCityName",produces="application/json") public String get

随机推荐