如果一个对象太复杂了,那么在网络传输键的JSON格式数据转换容易出问题。

比如下面一个类Area.java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon; @Data
@NoArgsConstructor
@AllArgsConstructor
public class Area { private String name;
private GeoJsonPolygon geoJsonPolygon;
}

在这个Area类中,有个属性GeoJsonPloygon有点复杂,这个类的源码我就不贴了,只给大家看一下Area对象中包含它的JSON格式数据表示:

{
"name": "AAAA",
"geoJsonPolygon": {
"points": [{
"x": 3.4,
"y": 3.9
}, {
"x": 6.2,
"y": 8.1
}, {
"x": 9.8,
"y": 3.1
}, {
"x": 3.4,
"y": 3.9
}],
"coordinates": [{
"type": "LineString",
"coordinates": [{
"x": 3.4,
"y": 3.9
}, {
"x": 6.2,
"y": 8.1
}, {
"x": 9.8,
"y": 3.1
}, {
"x": 3.4,
"y": 3.9
}]
}],
"type": "Polygon"
}
}

上面红色标识就是GeoJsonPolygon的JSON格式。

这里如果看不懂points和coordinates没关系。

下面模拟一个服务A向另一个服务B,传输泛型为Area的一个List,服务B解析该数据,并返回数据。

服务A的Controller,就是造一个泛型为Area的一个List,通过RestTemplate向B服务传数据。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate; import java.util.ArrayList;
import java.util.List; @RestController
public class SendController { @Autowired
private RestTemplate restTemplate; @GetMapping(value = "/send")
@ResponseBody
public List sendArea(){ Point point1 = new Point(3.4, 3.9);
Point point2 = new Point(6.2, 8.1);
Point point3 = new Point(9.8, 3.1);
Point point4 = new Point(3.4, 3.9);
List<Point> points = new ArrayList<>();
points.add(point1);
points.add(point2);
points.add(point3);
points.add(point4); List<Area> areaList = new ArrayList<>();
areaList.add(new Area("AAAA",new GeoJsonPolygon(points)));
areaList.add(new Area("BBBB",new GeoJsonPolygon(points)));
areaList.add(new Area("CCCC",new GeoJsonPolygon(points))); String url = ReceiveController.BASE_URL+ReceiveController.POST_MAPPING;
ResponseEntity entity = restTemplate.postForEntity(url, areaList,List.class);
List body = (List) entity.getBody(); return body;
} @Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}

服务B的Controller

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.geo.GeoJsonPolygon;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList;
import java.util.List; @RestController
public class ReceiveController {
public static final String BASE_URL = "http://localhost:8080";
public static final String POST_MAPPING = "/receive"; @PostMapping(value = POST_MAPPING)
@ResponseBody
public List areaList(@RequestBody String areaList){
List<Area> list = new ArrayList<>();
if(areaList == null ){
return list;
}
/**
* List<Area> listString = JSON.parseObject(areaList, new TypeReference<List<Area>>(){});
* 注意这样写是错误的,Area包含属性GeoJsonPolygon,解析不了
* 只好吧List的泛型写成String
*/
List<String> listString = JSON.parseObject(areaList, new TypeReference<List<String>>(){}); JSONObject jsonObject = null;
JSONObject polygonJsonObject = null; GeoJsonPolygon geoJsonPolygon = null;
for (int i=0; i < listString.size(); i++){
String s = listString.get(i);
jsonObject = JSONObject.parseObject(s);
//通过JSONObject对象获取key对应的value
String name = jsonObject.getString("name"); //解析复杂的GeoJsonPolygon属性
String geoJsonPolygonString = jsonObject.getString("geoJsonPolygon");
polygonJsonObject = JSONObject.parseObject(geoJsonPolygonString);
String pointsString = polygonJsonObject.getString("points");
List<Point> points = JSON.parseObject(pointsString, new TypeReference<List<Point>>() {});
geoJsonPolygon = new GeoJsonPolygon(points); Area area = new Area();
area.setName(name);
area.setGeoJsonPolygon(geoJsonPolygon); list.add(area);
} return list;
}
}

注意:使用的是fastjson版本是1.2.47,如果是1.2.7版本在执行这条语句List<Point> points = JSON.parseObject(pointsString, new TypeReference<List<Point>>() {}) 会报错,因为1.2.7要求这里的泛型类Point必须有无参构造函数,而1.2.47版本没有无参构造函数也可以。

总结

a. 服务B首先使用了@RequestBody注解,然后解析该嵌套数据类型;

b. 如果是list利用List<String> listString = JSON.parseObject(areaList, new TypeReference<List<String>>(){}) 先解析成泛型为String的List。因为GeoJsonPolygon太复杂了,直接解析不了,如果是简单的如Point可以直接List<Point> points = JSON.parseObject(pointsString, new TypeReference<List<Point>>() {});

c. 如果不是list,并且该String对象还是嵌套JSON数据格式,就把String对象解析成JsonObject 对象;

d. 利用JsonObject 对象的getString方法获取对应属性key的字符串,如果该字符串还是复杂的JSON数据,进行b或c步骤,直到获取到想要的数据或解析完成。

在线JSON:http://www.bejson.com/

												

网络传输中利用fastjson将复杂嵌套数据类型Json格式转换(GeoJsonPolygon)的更多相关文章

  1. Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

    MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明 ...

  2. Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完毕測试代码)

    MD5和RSA是网络传输中最经常使用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,仅仅能加密而不能解密. ...

  3. Android网络传输中必用的两个加密算法:MD5 和 RSA

    MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明 ...

  4. [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

    [转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...

  5. Android网络传输中必用的两个加密算法:MD5 和 RSA 及Base64加密总结

    (1)commons-codec包简介 包含一些通用的编码解码算法.包括一些语音编码器,Hex,Base64.MD5 一.md5.base64.commons-codec包 commons-codec ...

  6. Idea中:No converter found for return value of type: class java.util.ArrayList:Json格式转换问题

    1.在搞SSM框架的时候,前端发送请求后,显示如下错误. @ResponseBody注解进行返回List<对象>的json数据时出现 nested exception is java.la ...

  7. 获取一个表单字段中多条数据并转化为json格式

    如图需要获取下面两个li标签里面的数据,然后传给后台:而后台接收的数据格式是json的,所以需要把两个li里面的信息转化为以下格式的. {recieverName:小红,recieverPhone:1 ...

  8. 在thinkphp5.0中调用ajax时, 返回的JSON 格式数据在html前台不能用时

    在thinkphp5.0中调用ajax时,如果控制器返回的数据为json格式,视图层接收到返回值即为json格式的数据,此时应该把 JSON 文本转换为 JavaScript 对象,方便调用.具体代码 ...

  9. PHP中把数据库查询结果输出为json格式

    <?php header("Content-type:text/html;charset=utf-8");//字符编码设置 $servername = "local ...

随机推荐

  1. sersync+rsync实现服务器文件实时同步

    sersync+rsync实现服务器文件实时同步 一.为什么要用rsync+sersync架构? 1.sersync是基于inotify开发的,类似于inotify-tools的工具 2.sersyn ...

  2. javascript继承之学习笔记

    今天记录一下学习javascript的继承. 继承基本上是基于“类”来说的,而javascript中并不存在真正的类,所以就出现了各种模拟“类”的行为,然后就堂而皇之的使用起了类的概念.这里不谈“类” ...

  3. 性能测试day01_性能基本概念

    其实第一次接触性能是15年的时候,懵懵懂懂的被领导拉去做第一次做性能压测,如今有机会重新听一下云层大大讲解性能,于是打算以此博客记录下整个学习的过程,如若有不同意见者可以在下面留言指出,也欢迎大家一起 ...

  4. ubantu 上hadoop 搭建

    Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04 参考 http://www.powerxing.com/install-hadoop/ 2014-08-09 ...

  5. js全局变量污染

    一.定义全局变量命名空间 只创建一个全局变量,并定义该变量为当前应用容器,把其他全局变量追加在该命名空间下 var my={}; my.name={ big_name:"zhangsan&q ...

  6. thinkphp3.2.2有预览的多图上传

    thinkphp3.2.2有预览的多图上传 整体思路 1 封装文件上传和图片上传的类文件 2 视图中添加相关JS和表单提交 3 控制器中添加上传文件的相关代码 一 2个class 文件 请上传到/Th ...

  7. Python中的字符串方法

    Python中的字符串方法 字符串类即str提供了许多有用的方法来操纵字符串.具体来说,我们将讨论如下的方法. 搜索字符串内的子字符串. 测试字符串. 格式字符串. 转换字符串. 回顾前面的章节,方法 ...

  8. 使用RecyclerView打造Gallery

    RecyclerView概述 RecyclerView是谷歌推出的用于向大型数据集提供有限窗口的灵活视图.可以通过导入support-v7对其进行使用. 据官方的介绍,该控件用于在有限的窗口中展示大量 ...

  9. 【ASP.NET 进阶】仿百度文库文档在线预览(支持格式.pdf,.doc,docx,xls,xlsx,.ppt,pptx)

    在[ASP.NET]PDF文件在线预览(类似百度文库)基础上进行了office文件到pdf文件的转换,然后在显示出来,效果如下: 问题说明: 1.请通过以下方式添加 Office COM 组件. 2. ...

  10. Human Interface Device (HID) Class Decoder

    http://www.usblyzer.com/usb-human-interface-device-hid-class-decoder.htm   Human Interface Device (H ...