发现自己好久都没有更新博客了,工作比之前忙了,但是在学习方面也开始变懒了。废话不多说了,进入主题。最近项目中遇到了需要对Json进行封装和解析,由于之前没有接触过,走了很多弯路,一个周的工作结束了,就写一篇博客总结一下吧。
应用场景是这样的,前端首先通过接口将Json格式的信息传递到后端,后端对传过来的信息进行解析并且存入MySQL数据库中,然后当前端调用触发接口时,后端将信息从数据库中取出,并进行Json封装,通过Kafka生产者的方式将信息传递出去。
之前对于Json格式的信息,我都会用对象去进行解析,但是这次项目中所接收的Json格式有一些特殊。
{
"drone_id": "AB001",
"command_word": "set_home",
"params": {
"alt": "32.37",
"lon":"117.1275052",
"lat":"36.7103392"
},
"control_object":"0"
}
这是一个DroneOrder对象,其中包含drone_id,command_word,params和control_object等几个属性,除了"params"之外,其余几个属性均为String类型。由于不同的命令接收的params是不同的,所以无法将params定义为一个类。那如何进行接收呢?最终通过调研,选定了阿里的JSON工具包。maven依赖如下:
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.28version>
dependency>
我们把params属性定义为一个JSONObject类型的对象,但是这又遇到了一个问题,如何将params存到数据库中呢,在数据库中要使用什么类型进行接收呢?通过对源码的查询,使用JSONObject对象中的toJSONString()方法,将params的类型转为String,存到数据库中。
public String toJSONString() {
SerializeWriter out = new SerializeWriter();
String var2;
try {
(new JSONSerializer(out)).write(this);
var2 = out.toString();
} finally {
out.close();
}
return var2;
}
在本项目中需要将存储在数据库中的Json格式的字符串转化为Java对象(List),最终使用了JSONArray.parseObject(String text, TypeReference type, Feature… features)这个静态方法将String类型deJSON串转化为JAVA对象。
public static <T> T parseObject(String text, TypeReference<T> type, Feature... features) {
return parseObject(text, type.type, ParserConfig.global, DEFAULT_PARSER_FEATURE, features);
}
在对JAVA对象进行封装时,需要将将String类型的对象封装为JSON对象。
要将DroneOrder对象封装为如下形式的JSON对象,DroneOrder对象的字段都是以varchar类型存放在数据库中的。
{
"drone_id": "AB001",
"command_word": "waypoint_mission",
"params": {"waypoints":
[{"lat": "36.7100807","lon": "117.1275529","alt": "75.33"},
{"lat": "36.7100093","lon": "117.1275127","alt": "38.3"}
]
},
"control_object": "0"
}
对于JSONObject类型的params,由于数据库中存放的是waypoints中的内容,所以要进行两次封装,首先将数据库中的String类型的Json数组解析为JavaList对象,然后在封装为map类型,最后将该map类型的Java对象封装为Json对象。
List<WayPoint>wps=JSONArray.parseObject(executeAirway.getWaypoints(),new TypeReference<List<WayPoint>>(){});
Map<String,List<WayPoint>> map=new HashMap<>();
map.put("waypoints",wps);
droneOrder.setParams((JSONObject)JSONObject.toJSON(map));