前言
大家好,欢迎来到软件工程师令狐本期文章。最近做一个中间件项目的时候,涉及到从第三方系统收数据过来到我们自己的系统,我拿对象去接收就一定要涉及到对象的序列化与反序列化。我本来用的是阿里巴巴的FastJson,但我发现这个工具其实很不稳定,性能不太好。我调研发现Gson是目前性能最稳定的项目。
在我做项目重构升级的时候,我决定序列化工具改成Gson!这篇文章就是介绍Gson相关的知识点与应用。
[TOC]
关于对象的序列化与反序列化
这两个概念不难理解。
序列化
JavaBean转换为json字符串。【比较粗暴的理解】
反序列化
Json字符串转换为JavaBean【比较粗暴的理解】
快速入门 | Demo
序列化有三种场景,分别是:
- JavaBean转换为Json字符串
- List集合转Json字符串
- Map集合转Json字符串
依赖引入
这个Gson其实是Google公司推出的,个人比较推荐。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
定义JavaBean
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private int age;
private String sex;
private List<String> hobbies;
}
Person作为我们要用的统一实体类,后面会一直使用。
JavaBean转换为Json字符串
Gson gson = new Gson(); 生成一个gson工具,要用到的工具函数就是 toJson()
/** 将JavaBean转换为json,或将json字符串转换为JavaBean。 */
@Test
public void testBeantoJson(){
Person person = new Person("linghu",26,"男",Arrays.asList("打球","看电影"));
Gson gson = new Gson();
String json = gson.toJson(person);
System.out.println("json字符串为:"+json);
}
List集合转Json字符串
@Test
public void testListToJson(){
List<Person> list = new ArrayList<>();
list.add(new Person("linghu",26,"男",Arrays.asList("打球","看电影")));
list.add(new Person("zhangsan",16,"男",Arrays.asList("吃火锅","看电影")));
Gson gson = new Gson();
String jsonList = gson.toJson(list);
System.out.println("jsonList为:"+jsonList);
// List fromJson = gson.fromJson(jsonList, List.class);//这种方法不安全,不推荐
List<Person> fromJson = gson.fromJson(jsonList, new TypeToken<List<Person>>() {}.getType());
System.out.println("---------------------");
fromJson.stream().forEach(System.out::println);
}
jsonList为:[{"name":"linghu","age":26,"sex":"男","hobbies":["打球","看电影"]},{"name":"zhangsan","age":16,"sex":"男","hobbies":["吃火锅","看电影"]}]
---------------------
Person(name=linghu, age=26, sex=男, hobbies=[打球, 看电影])
Person(name=zhangsan, age=16, sex=男, hobbies=[吃火锅, 看电影])
Map集合转Json字符串
@Test
public void testMapToJson(){
Map<String, Person> hashMap = new HashMap<>();
hashMap.put("p1", new Person("linghu",26,"男",Arrays.asList("打球","看电影")));
hashMap.put("p2", new Person("zhangsan",16,"男",Arrays.asList("吃火锅","看电影")));
Gson gson = new Gson();
String json = gson.toJson(hashMap);
System.out.println("json字符串:"+json);
System.out.println("---------------------");
Map<String, Person> jsonMap = gson.fromJson(json, new TypeToken<Map<String, Person>>() {}.getType());
for (Map.Entry<String, Person> personEntry : jsonMap.entrySet()) {
System.out.println("key:"+personEntry.getKey()+" value:"+personEntry.getValue());
}
}
json字符串:{"p1":{"name":"linghu","age":26,"sex":"男","hobbies":["打球","看电影"]},"p2":{"name":"zhangsan","age":16,"sex":"男","hobbies":["吃火锅","看电影"]}}
---------------------
key:p1 value:Person(name=linghu, age=26, sex=男, hobbies=[打球, 看电影])
key:p2 value:Person(name=zhangsan, age=16, sex=男, hobbies=[吃火锅, 看电影])
Json字符串转JavaBean
要用到的工具函数就是 fromJson()
@Test
public void testBeantoJson(){
Person person = new Person("linghu",26,"男",Arrays.asList("打球","看电影"));
Gson gson = new Gson();
System.out.println("---------------------");
Person personObeject = gson.fromJson(json, Person.class);
System.out.println("Person对象为:"+personObeject);
}
Gson实战 | 牛刀小试
当我们真的拿到一组数据的时候,我们需要去不断拆解,需要不断序列化和反序列化。
我们一定要用的工具就是在线json转换工具:www.json.cn/
用在线工具的目的是看清楚数据结构,分析如何拿到我们想要的字段-对应的数据值。
案例:
String message = "{\"orderId\":\"example\",\"appProductId\":\"example\",\"productId\":\"example\",\"productName\":\"example\",\"begintime\":\"example\",\"duration\":\"example\",\"endtime\":\"example\",\"products\":\"[{\\\"app_product_id\\\":\\\"example\\\",\\\"app_sku_id\\\":\\\"example\\\",\\\"product_id\\\":1000,\\\"sku_id\\\":\\\"example\\\",\\\"quantity\\\":1,\\\"amount\\\":\\\"example\\\",\\\"desc\\\":\\\"example\\\",\\\"product_type\\\":1,\\\"related_product\\\":\\\"example\\\",\\\"card_total_number\\\":1,\\\"card_consumption_number\\\":1,\\\"card_remain_number\\\":1,\\\"adv_service_techId\\\":\\\"example\\\",\\\"period_orderId\\\":\\\"example\\\",\\\"uni_order_id\\\":\\\"example\\\",\\\"product_name\\\":\\\"example\\\"}]\",\"userName\":\"example\",\"userGender\":\"example\",\"mobile\":\"example\",\"appPeriodId\":\"example\",\"userAge\":\"example\",\"identityNum\":\"example\",\"chargeMode\":\"example\",\"married\":\"example\",\"amount\":\"example\",\"orderShoppromoDetails\":\"[{\\\"promo_type\\\":1,\\\"promo_amount\\\":\\\"example\\\",\\\"desc\\\":\\\"example\\\"}]\",\"quantity\":\"example\",\"comment\":\"example\",\"bizType\":\"example\",\"relatedServiceItem\":[{\"price\":\"example\",\"quantity\":1,\"sku_id\":\"example\",\"app_sku_id\":\"example\",\"app_product_id\":\"example\"}],\"userAddress\":\"{\\\"receiver_name\\\":\\\"example\\\",\\\"receiver_address\\\":\\\"example\\\",\\\"remark\\\":\\\"example\\\",\\\"latitude\\\":\\\"example\\\",\\\"use_receiver_virtual_number\\\":\\\"example\\\",\\\"longitude\\\":\\\"example\\\",\\\"receiver_mobile\\\":\\\"example\\\",\\\"receiver_phone\\\":\\\"example\\\"}\",\"type\":\"example\",\"deliveryAddress\":\"{}\",\"phone\":\"example\",\"useVirtualNumber\":\"example\",\"lockReceipt\":\"example\",\"platform\":\"example\",\"acceptType\":\"example\",\"techId\":\"example\"}";
上面的message是我们获取到的某个三方系统给我们的数据,我们接下来如何获取里面对应想要的值呢?
json转换
用在线工具www.json.cn/ 首先把上面的数据结构展示出来:
- 一开始我们可以根据对应的字段新建对应的实体类
- 分析对应的字段是什么数据结构 ??map or List?List里装了很多个json?
- 取出对应值填充到我们建好的实体类里作为新的对象
@Test
public void test(){
String message = "{\"orderId\":\"example\",\"appProductId\":\"example\",\"productId\":\"example\",\"productName\":\"example\",\"begintime\":\"example\",\"duration\":\"example\",\"endtime\":\"example\",\"products\":\"[{\\\"app_product_id\\\":\\\"example\\\",\\\"app_sku_id\\\":\\\"example\\\",\\\"product_id\\\":1000,\\\"sku_id\\\":\\\"example\\\",\\\"quantity\\\":1,\\\"amount\\\":\\\"example\\\",\\\"desc\\\":\\\"example\\\",\\\"product_type\\\":1,\\\"related_product\\\":\\\"example\\\",\\\"card_total_number\\\":1,\\\"card_consumption_number\\\":1,\\\"card_remain_number\\\":1,\\\"adv_service_techId\\\":\\\"example\\\",\\\"period_orderId\\\":\\\"example\\\",\\\"uni_order_id\\\":\\\"example\\\",\\\"product_name\\\":\\\"example\\\"}]\",\"userName\":\"example\",\"userGender\":\"example\",\"mobile\":\"example\",\"appPeriodId\":\"example\",\"userAge\":\"example\",\"identityNum\":\"example\",\"chargeMode\":\"example\",\"married\":\"example\",\"amount\":\"example\",\"orderShoppromoDetails\":\"[{\\\"promo_type\\\":1,\\\"promo_amount\\\":\\\"example\\\",\\\"desc\\\":\\\"example\\\"}]\",\"quantity\":\"example\",\"comment\":\"example\",\"bizType\":\"example\",\"relatedServiceItem\":[{\"price\":\"example\",\"quantity\":1,\"sku_id\":\"example\",\"app_sku_id\":\"example\",\"app_product_id\":\"example\"}],\"userAddress\":\"{\\\"receiver_name\\\":\\\"example\\\",\\\"receiver_address\\\":\\\"example\\\",\\\"remark\\\":\\\"example\\\",\\\"latitude\\\":\\\"example\\\",\\\"use_receiver_virtual_number\\\":\\\"example\\\",\\\"longitude\\\":\\\"example\\\",\\\"receiver_mobile\\\":\\\"example\\\",\\\"receiver_phone\\\":\\\"example\\\"}\",\"type\":\"example\",\"deliveryAddress\":\"{}\",\"phone\":\"example\",\"useVirtualNumber\":\"example\",\"lockReceipt\":\"example\",\"platform\":\"example\",\"acceptType\":\"example\",\"techId\":\"example\"}";
Gson gson = new Gson();
Map<String, Object> o = gson.fromJson(message, new TypeToken<Map<String, Object>>() {}.getType());
OrderMessage orderMessage = new OrderMessage();
for (Map.Entry<String, Object> entry : o.entrySet()) {
System.out.println("key:"+entry.getKey()+" value:"+entry.getValue());
if (entry.getKey().equals("orderId")){
orderMessage.setOrderId((String) entry.getValue());
}
if (entry.getKey().equals("products") && StringUtils.isNotBlank(entry.getKey())){
// System.out.println("products:"+entry.getValue());
List<Map<String, Object>> products = gson.fromJson(entry.getValue().toString(), new TypeToken<List<Map<String, Object>>>() {}.getType());
for (Map<String, Object> maps :products) {
// System.out.println(maps);
Double quantity = (Double) maps.get("quantity");
// System.out.println("quantity:"+quantity);
}
}
if (entry.getKey().equals("appProductId")){
orderMessage.setAppProductId((String) entry.getValue());
}
if (entry.getKey().equals("orderShoppromoDetails")){
OrderShoppromoDetails orderShoppromoDetails = new OrderShoppromoDetails();
List<Map<String, Object>> o1 =gson.fromJson(entry.getValue().toString(),new TypeToken<List<Map<String, Object>>>() {}.getType());
for (Map<String, Object> stringObjectMap :o1) {
log.info("map:{}",stringObjectMap);
if (stringObjectMap!=null){
orderShoppromoDetails.setPromo_type((Double) stringObjectMap.get("promo_type"));
orderShoppromoDetails.setDesc((String) stringObjectMap.get("desc"));
orderShoppromoDetails.setPromo_amount((String) stringObjectMap.get("promo_amount"));
}
}
orderMessage.setOrderShoppromoDetails(orderShoppromoDetails);
}
if (entry.getKey().equals("relatedServiceItem")){
RelatedServiceItem relatedServiceItem = new RelatedServiceItem();
List<Map<String, Object>> item = gson.fromJson(entry.getValue().toString(),new TypeToken<List<Map<String, Object>>>() {}.getType());
for (Map<String,Object> stringObjectMap :item) {
if (stringObjectMap!=null){
relatedServiceItem.setPrice((String) stringObjectMap.get("price"));
relatedServiceItem.setQuantity((Double) stringObjectMap.get("quantity"));
relatedServiceItem.setSku_id((String) stringObjectMap.get("sku_id"));
relatedServiceItem.setApp_sku_id((String) stringObjectMap.get("app_sku_id"));
relatedServiceItem.setApp_product_id((String) stringObjectMap.get("app_product_id"));
}
}
orderMessage.setRelatedServiceItem(relatedServiceItem);
}
if (entry.getKey().equals("userAddress")){
UserAddress userAddress = new UserAddress();
Map<String, Object> mapLists = gson.fromJson(entry.getValue().toString(),new TypeToken<Map<String, Object>>() {}.getType());
if (!mapLists.isEmpty()){
userAddress.setReceiver_name((String) mapLists.get("receiver_name"));
userAddress.setReceiver_address((String) mapLists.get("receiver_address"));
userAddress.setRemark((String) mapLists.get("remark"));
userAddress.setLatitude((String) mapLists.get("latitude"));
userAddress.setUse_receiver_virtual_number((String) mapLists.get("use_receiver_virtual_number"));
userAddress.setLongitude((String) mapLists.get("longitude"));
userAddress.setReceiver_mobile((String) mapLists.get("receiver_mobile"));
userAddress.setReceiver_phone((String) mapLists.get("receiver_phone"));
}
orderMessage.setUserAddress(userAddress);
}
}
log.info("orderMessage:{}",orderMessage);
}
gson.fromJson(entry.getValue().toString(),new TypeToken<List<Map<String, Object>>>() {}.getType());这种用法是我特别喜欢的一类用法。非常灵活。在Gson库中,gson.fromJson() 方法用于将JSON字符串反序列化为Java对象。new TypeToken<List<Map<String, Object>>>() {}.getType():这是一个类型令牌(Type Token),用于指定fromJson()方法应该期望的返回类型。在这个例子中,你期望的是一个List,其中包含了Map<String, Object>类型的元素。Gson使用这种类型令牌技术来在运行时捕获泛型类型信息,因为Java的泛型在编译时会被类型擦除。