前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >特殊数据格式处理-JSON框架Jackson精解第2篇

特殊数据格式处理-JSON框架Jackson精解第2篇

作者头像
字母哥博客
发布2020-09-23 15:52:21
1.7K0
发布2020-09-23 15:52:21
举报

Jackson是Spring Boot默认的JSON数据处理框架,但是其并不依赖于任何的Spring 库。有的小伙伴以为Jackson只能在Spring框架内使用,其实不是的,没有这种限制。它提供了很多的JSON数据处理方法、注解,也包括流式API、树模型、数据绑定,以及复杂数据类型转换等功能。它虽然简单易用,但绝对不是小玩具,本节为大家介绍Jackson的基础核心用法,更多的内容我会写成一个系列,5-10篇文章,请您继续关注我。

本篇文章中为大家介绍,一些特殊JOSN数据格式处理-JSON框架Jackson精解第2篇:

  • 一、从URL读取JSON数据
  • 二、Unknow Properties 赋值失败处理
  • 三、未赋值Java Bean序列化
  • 四、日期格式化

一、从URL读取JSON数据

Jackson不仅可以将字符串反序列化为 Java POJO对象,还可以请求远程的API,获得远程服务的JSON响应结果,并将其转换为Java POJO对象。

代码语言:javascript
复制
@Test
void testURL() throws IOException {

  URL url = new URL("https://jsonplaceholder.typicode.com/posts/1"); //远程服务URL
  ObjectMapper mapper = new ObjectMapper();
  //从URL获取JSON响应数据,并反序列化为java 对象
  PostDTO postDTO = mapper.readValue(url, PostDTO.class); 

  System.out.println(postDTO);

}
  • jsonplaceholder.typicode.com 是一个免费提供HTTP测试服务的网站,我们可以利用它进行测试
  • 远程服务API返回结果是一个JSON字符串,一篇post稿件包含userId,id,title,content属性
  • PostDTO 是我们自己定义的java 类,同样包含userId,id,title,content成员变量

下文是控制台打印输出结果,postDTO的toString()方法输出。

代码语言:javascript
复制
PostDTO(userId=1, id=1, title=sunt aut facere repellat provident occaecati excepturi optio reprehenderit, body=quia et suscipit
suscipit recusandae consequuntur expedita et cum
reprehenderit molestiae ut ut quas totam
nostrum rerum est autem sunt rem eveniet architecto)

二、Unknow Properties 赋值失败处理

有的时候,客户端提供的JSON字符串属性,多于我们服务端定义的java 类的成员变量。

比如上图中的两个类,

  • 我们先将PlayerStar序列化为JSON字符串,包含age属性
  • 然后将JSON字符串转换为PlayerStar2,不包含age属性
代码语言:javascript
复制
@Test
void testUnknowProperties() throws IOException {
  ObjectMapper mapper = new ObjectMapper();
  PlayerStar player = PlayerStar.getInstance(); //为PlayerStar 各属性赋值,可以参考本系列文章第一篇

  //将PlayerStar序列化为JSON字符串
  String jsonString = mapper.writeValueAsString(player);
  System.out.println(jsonString);
  //将JSON字符串反序列化为PlayerStar2对象
  PlayerStar2 player2 = mapper.readValue(jsonString, PlayerStar2.class);
  System.out.println(player2);
}

当进行反序列化的时候,会抛出下面的异常。这是因为JSON字符串所包含的属性,多余Java类的定义(多出一个阿age,赋值时找不到setAge方法)。

代码语言:javascript
复制
{"age":45,"playerName":"乔丹"}

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "age" (class com.example.demo.javabase.PlayerStar2), not marked as ignorable (one known property: "playerName"])
 at [Source: (String)"{"age":45,"playerName":"乔丹"}"; line: 1, column: 10] (through reference chain: com.example.demo.javabase.PlayerStar2["age"])

如果我们想忽略掉age属性,不接受我们的java类未定义的成员变量数据,可以使用下面的方法,就不会抛出UnrecognizedPropertyException了。

代码语言:javascript
复制
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

三、未赋值Java Bean序列化

有的时候,我们明知道某些类的数据可能为空,我们通常也不会为它赋值。但是客户端就是需要这个{}的JSON对象,我们该怎么做?

代码语言:javascript
复制
public class MyEmptyObject {
  private Integer i;  //没有get set方法
}

我们可以为ObjectMapper设置disable序列化特性:FAIL_ON_EMPTY_BEANS,也就是允许对象的所有属性均未赋值。

代码语言:javascript
复制
@Test
void testEmpty() throws IOException {

  ObjectMapper mapper = new ObjectMapper();
  mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

  String jsonString = mapper.writeValueAsString(new MyEmptyObject());
  System.out.println(jsonString);

}

默认情况下不做设置,会抛出下面的异常InvalidDefinitionException。设置disable序列化特性:FAIL_ON_EMPTY_BEANS之后,会序列化为{}字符串。

代码语言:javascript
复制
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: No serializer found for class com.example.demo.jackson.JacksonTest1$MyEmptyObject and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

四、日期格式化

日期格式化,是我们JSON序列化与反序列化过程中比较常见的需求

代码语言:javascript
复制
ObjectMapper mapper = new ObjectMapper();
Map temp = new HashMap();
temp.put("now", new Date());
String s = mapper.writeValueAsString(temp);
System.out.println(s);

默认情况下,针对java中的日期及相关类型,Jackson的序列化结果如下

代码语言:javascript
复制
{"now":1600564582571}

如果我们希望在JSON序列化及反序列化过程中,日期格式化,需要做如下的处理

代码语言:javascript
复制
ObjectMapper mapper = new ObjectMapper();
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);  //注意这里
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));  //注意这里
Map temp = new HashMap();
temp.put("now", new Date());

String s = mapper.writeValueAsString(temp);
System.out.println(s);

控制台打印输出结果如下:

代码语言:javascript
复制
{"now":"2020-09-20"}

喜欢 (0)or分享 (0)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、从URL读取JSON数据
  • 二、Unknow Properties 赋值失败处理
  • 三、未赋值Java Bean序列化
  • 四、日期格式化
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档