关于spring:URL及日期等特殊数据格式处理JSON框架Jackson精解第2篇

29次阅读

共计 3782 个字符,预计需要花费 10 分钟才能阅读完成。

Jackson 是 Spring Boot 默认的 JSON 数据处理框架,然而其并不依赖于任何的 Spring 库。有的小伙伴认为 Jackson 只能在 Spring 框架内应用,其实不是的,没有这种限度。它提供了很多的 JSON 数据处理办法、注解,也包含 流式 API、树模型、数据绑定 ,以及简单数据类型转换等性能。它尽管简略易用,但相对不是小玩具,本节为大家介绍 Jackson 的根底外围用法, 更多的内容我会写成一个系列,5-10 篇文章,请您持续关注我。

  • 在《序列化与反序列化外围用法 -JSON 框架 Jackson 精解第一篇》也就是上一篇中,为大家介绍了这些内容

    • 一、根底筹备
    • 二、序列化办法
    • 三、反序列化办法
    • 四、字段重命名@JsonProperty
    • 五、疏忽 null 字段的序列化@JsonInclude
    • 六、疏忽指定的字段

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

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

一、从 URL 读取 JSON 数据

Jackson 不仅能够将字符串反序列化为 Java POJO 对象,还能够申请近程的 API,取得近程服务的 JSON 响应后果,并将其转换为 Java POJO 对象。

@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()办法输入。

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 属性
@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 办法)。

{"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 了。

ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

三、未赋值 Java Bean 序列化

有的时候,咱们明晓得某些类的数据可能为空,咱们通常也不会为它赋值。然而客户端就是须要这个 {} 的 JSON 对象,咱们该怎么做?

public class MyEmptyObject {private Integer i;  // 没有 get set 办法}

咱们能够为 ObjectMapper 设置 disable 序列化个性:FAIL_ON_EMPTY_BEANS, 也就是容许对象的所有属性均未赋值。

@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 之后,会序列化为 {} 字符串。

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 序列化与反序列化过程中比拟常见的需要

ObjectMapper mapper = new ObjectMapper();
Map temp = new HashMap();
temp.put("now", new Date());
String s = mapper.writeValueAsString(temp);
System.out.println(s);

默认状况下,针对 java 中的日期及相干类型,Jackson 的序列化后果如下

{"now":1600564582571}

如果咱们心愿在 JSON 序列化及反序列化过程中,日期格式化,须要做如下的解决

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);

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

{"now":"2020-09-20"}

欢送关注我的博客,外面有很多精品合集

本文转载注明出处(必须带连贯,不能只转文字):字母哥博客 – zimug.com

正文完
 0