今天在解析json数据的时候得到了一堆这样的数据:{"errNum":0,"errMsg":"success","retData":[{"title":"\u6536\u5e9f\u54c1\u5927\u53d4\u521a\u4e0a\u53f0\uff0c\u5c31\u60e8\u906d\u8bc4\u59d4\u706d\u706f\uff0c\u4f46\u63a5\u4e0b\u6765\u5168\u573a\u90fd\u9707\u60ca\u4e86\uff01","url":"http:\/\/toutiao.com\/group\/6263036756505920002\/","abstract":"\u8ba2\u9605\u6211\u83b7\u53d6\u66f4\u591a\u7cbe\u5f69\u5185\u5bb9\uff01","image_url":"http:\/\/p1.pstatp.com\/list\/2f90009a31a7ee8bb15"}]}

这是因为,为了更好的传输中文,json进行了Unicode编码。

这样一来,我们在解析json之前,就得要先将json数据中的Unicode编码转换为我们使用的中文;

一:http请求数据返回json中string字段包含unicode的转码

  1. public static String decodeUnicode(String theString) {
  2. char aChar;
  3. int len = theString.length();
  4. StringBuffer outBuffer = new StringBuffer(len);
  5. for (int x = 0; x < len;) {
  6. aChar = theString.charAt(x++);
  7. if (aChar == '\\') {
  8. aChar = theString.charAt(x++);
  9. if (aChar == 'u') {
  10. // Read the xxxx
  11. int value = 0;
  12. for (int i = 0; i < 4; i++) {
  13. aChar = theString.charAt(x++);
  14. switch (aChar) {
  15. case '0':
  16. case '1':
  17. case '2':
  18. case '3':
  19. case '4':
  20. case '5':
  21. case '6':
  22. case '7':
  23. case '8':
  24. case '9':
  25. value = (value << 4) + aChar - '0';
  26. break;
  27. case 'a':
  28. case 'b':
  29. case 'c':
  30. case 'd':
  31. case 'e':
  32. case 'f':
  33. value = (value << 4) + 10 + aChar - 'a';
  34. break;
  35. case 'A':
  36. case 'B':
  37. case 'C':
  38. case 'D':
  39. case 'E':
  40. case 'F':
  41. value = (value << 4) + 10 + aChar - 'A';
  42. break;
  43. default:
  44. throw new IllegalArgumentException(
  45. "Malformed   \\uxxxx   encoding.");
  46. }
  47. }
  48. outBuffer.append((char) value);
  49. } else {
  50. if (aChar == 't')
  51. aChar = '\t';
  52. else if (aChar == 'r')
  53. aChar = '\r';
  54. else if (aChar == 'n')
  55. aChar = '\n';
  56. else if (aChar == 'f')
  57. aChar = '\f';
  58. outBuffer.append(aChar);
  59. }
  60. } else
  61. outBuffer.append(aChar);
  62. }
  63. return outBuffer.toString();
  64. }

二、普通string含有unicode转码方法

  1. public static String reEncoding(String text, String newEncoding) {
  2. String str = null;
  3. try {
  4. str = new String(text.getBytes(), newEncoding);
  5. } catch (UnsupportedEncodingException e) {
  6. log.error("不支持的字符编码" + newEncoding);
  7. throw new RuntimeException(e);
  8. }
  9. return str;
  10. }

三、说一下比较奇怪的方案,测试中无意发现的,暂时没弄明白原理(有明白原理的大神,请告知一声,谢谢)

我用HttpClent的post方式获取的json数据,得到的是带Unicode码的数据,需要转换成中文才行,但是转换的时间感觉有点长,就用HttpURLConnection的get方式又试了一下,在不转码的情况下,经过gson解析后,竟然神奇的自动转换成了中文:

简直是太神奇了,而且需要的时间相对于HttpClient的post请求方式的请求和处理时间更短,所以,果断换用HttpURLConnection的get方式了

①现在先贴一下HttpURLConnection的get的方式:

  1. @Test
  2. public void test() {
  3. try {
  4. long start = System.currentTimeMillis();
  5. URL url = new URL("http://apis.baidu.com/songshuxiansheng/news/news");
  6. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  7. connection.addRequestProperty("apikey","0fc807e45a37ce264f45d169646f4a9e" );
  8. String dataString = new String(GsonTools.IsToByte(connection.getInputStream()),"utf-8");
  9. HeadlineJson newsJson = GsonTools.getObjectData(dataString, HeadlineJson.class);
  10. List<Headline>list = newsJson.getRetData();
  11. System.out.println(list.toString());
  12. long end = System.currentTimeMillis();
  13. System.out.println("timeGap:"+(end-start));
  14. } catch (Exception e) {
  15. // TODO Auto-generated catch block
  16. e.printStackTrace();
  17. }
  18. }

调用的GsonTools的方法:(之前的博文中有写到过)

  1. public static <T> T getObjectData(String jsonString, Class<T> type) {
  2. T t = null;
  3. try {
  4. Gson gson = new Gson();
  5. t = gson.fromJson(jsonString, type);
  6. } catch (JsonSyntaxException e) {
  7. // TODO Auto-generated catch block
  8. e.printStackTrace();
  9. }
  10. return t;
  11. }

②然后贴一下HttpClient的post方式:

  1. @Test
  2. public void TestHeadLine() {
  3. long start = System.currentTimeMillis();
  4. List<NameValuePair> params = new ArrayList<NameValuePair>();
  5. String url = "http://apis.baidu.com/songshuxiansheng/news/news";
  6. String jsonString = HttpUtils.getBaiDuString2(url, params);
  7. HeadlineJson lineJson = GsonTools.getObjectData(jsonString, HeadlineJson.class);
  8. System.out.println(lineJson.toString());
  9. long end = System.currentTimeMillis();
  10. System.out.println("timeGap:"+(end-start));
  11. }

调用的HttpUtils的方法:

  1. public static String getBaiDuString(String url,List<NameValuePair> params) {
  2. String serverDataString = null;
  3. HttpPost post = new HttpPost(url);
  4. try {
  5. post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
  6. post.addHeader("apikey", UrlUtils.BAIDU_API_KEY);
  7. HttpClient client = new DefaultHttpClient();
  8. HttpResponse response = client.execute(post);
  9. int code = response.getStatusLine().getStatusCode();
  10. System.out.println("StatusCode:" + code);
  11. if (code == 200) {
  12. serverDataString = decodeUnicode(EntityUtils.toString(response.getEntity()));
  13. //              serverDataString = EntityUtils.toString(response.getEntity());
  14. System.out.println("接收字符串数据成功\nServerData:"+serverDataString);
  15. }
  16. } catch (Exception e) {
  17. // TODO Auto-generated catch block
  18. e.printStackTrace();
  19. }
  20. return serverDataString;
  21. }

③调用的HttpClient的get方式

  1. public static String getBaiDuString2(String url,List<NameValuePair> params) {
  2. String serverDataString = null;
  3. HttpGet get = new HttpGet(url);
  4. try {get.addHeader("apikey", UrlUtils.BAIDU_API_KEY);
  5. HttpClient client = new DefaultHttpClient();
  6. HttpResponse response = client.execute(get);
  7. int code = response.getStatusLine().getStatusCode();
  8. System.out.println("StatusCode:" + code);
  9. if (code == 200) {
  10. //              serverDataString = decodeUnicode(EntityUtils.toString(response.getEntity()));
  11. serverDataString = EntityUtils.toString(response.getEntity());
  12. System.out.println("接收字符串数据成功\nServerData:"+serverDataString);
  13. }
  14. } catch (Exception e) {
  15. // TODO Auto-generated catch block
  16. e.printStackTrace();
  17. }
  18. return serverDataString;
  19. }

谷歌提供的HttpClient的通信和HttpURLConnection网络通信的时间间隔我也做了比较,明显,HttpURLConnection的请求时间更短,所以果断使用HttpURLConnection的方式

四、java中本身就提供了对Unicode 的url进行解码的方法了:

    1. System.out.println(URLDecoder.decode("\u82f9\u679c", "utf-8"));  详细介绍请查看全文:https://cnblogs.com/qianzf/

通过http.client解析url返回的数据时为什么中文变成了unicode码的更多相关文章

  1. 【原创】@ResponseBody返回json数据时出现中文乱码

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 原因: Spring中解析字符串的转换器默认编码格式是ISO-8859-1 public class StringHttpMessageCon ...

  2. Mock拦截请求URL返回模板数据

    背景 : 前后端开发依赖后端数据, 当前端页面开发完成 ,后端在没有提供前端数据的情况下 ,前端无法测试, 导致开发效率低 ,速度慢 ,为了解决这一问题 ,通过Mock模拟生成数据在不改变原有代码前提 ...

  3. 如何解析Json返回的数据

    Json在Web开发的用处非常广泛,作为数据传递的载体,如何解析Json返回的数据是非常常用的.下面介绍下四种解析Json的方式: Part 1 var list1 = [1,3,4]; alert( ...

  4. SpringMVC返回JSON数据时日期格式化问题

    https://dannywei.iteye.com/blog/2022929 SpringMVC返回JSON数据时日期格式化问题 博客分类: Spring   在运用SpringMVC框架开发时,可 ...

  5. (转)MySQL 插入数据时,中文乱码问题的解决

    MySQL 插入数据时,中文乱码问题的解决  原文:http://www.cnblogs.com/sunzn/archive/2013/03/14/2960248.html 当向 MySQL 数据库插 ...

  6. java 解析http返回xml数据

    //post 请求 private static String sendPost(String url, String urlParameters) throws Exception { URL ob ...

  7. jquery easyui 解析数据库返回的数据

  8. springMVC返回json数据时date类型数据被转成long类型

    在项目的过程中肯定会遇到ajax请求,但是再用的过程中会发现,在数据库中好好的时间类型数据:2017-05-04 17:52:24 在转json的时候,得到的就不是时间格式了 而是145245121这 ...

  9. SpringMVC 配置.html拦截时,返回JSON数据时出现406错误解决方案

    [说明]在SpringMVC框架的使用中常常会使用@ResponseBody注解,修饰"处理器"(Controller的方法),这样在处理器在返回完毕后,就不走逻辑视图,而是将返回 ...

随机推荐

  1. Python3 reversed 函数

    Python3 reversed 函数  Python3 内置函数 描述 reversed 函数返回一个反转的迭代器. 语法 以下是 reversed 的语法: reversed(seq) 参数 se ...

  2. 贪吃蛇 Java实现(一)

    贪吃蛇  Java实现 1.面向对象思想 1.创建antition包它是包含sanke  Ground Food类 2.创建Controller包controller类 3.创建Game包有game类 ...

  3. 今天清理C盘空间,发现Unity的一个问题

    C:\Users\Acer\AppData\LocalLow\Unity\Caches\GiCache AppData目录下,Unity占用了大量C盘空间,大概有5,6个G

  4. Unity 场景分页插件 World Streamer 支持无限大地图的解决方案(二)

    Terrain Streaming 可以用WorldCreator创建Tile地形,然后用WorldStreamer实现分块地图.比如10000*10000(16平方公里) 的地形,需要1000*10 ...

  5. Angular之RouterModule的forRoot与forChild

    Angular 提供了一种方式来把服务提供商从模块中分离出来,以便模块既可以带着 providers 被根模块导入,也可以不带 providers 被子模块导入. 区别: `forRoot` crea ...

  6. ubuntu系列-安装jdk以及eclipse(for C++)

    1.安装jdk eclipse是使用java语言开发的,一个java应用程序的运行要在java虚拟机下.在没有安装jdk的前提下,即使在ubuntu上安装了eclipse也不能使用. (1)首先在官网 ...

  7. java 线程Thread 技术--1.5 Executor Executors,ThreadPool,Queue

    Executors : Executors ,就是一个线程工具类:大部分操作线程的方法,都可以在这个工具类中就行创建,执行,调用一些线程的方法: Executor : 用于执行和提交一个runnabl ...

  8. java ATM模拟程序

    //基本功能已经完善,文件读取没有问题,文件重写尚未完成. Account类 public class Account { //初始化参数 private String accountID; priv ...

  9. jsplumb踩坑

    一,,关于连线器label 我们全局设置中可以用 getInstance 实例化新对象 也可以通过 importDefaults 实例化新对象 当我想要给连线器上添加标签  每个连线器上的标签都不一样 ...

  10. Service Broker 概述

    ServiceBroker(简称SSB)是基于数据库引擎提供的一个强大的异步编程模型,通过ServiceBroker,开发人员无需编写复杂的通信和消息程序,即可在数据库实例之间完成高效可靠的异步通信. ...