简介

  • JSON是JavaScript Object Notation的缩写,它去除了所有JavaScript执行代码,只保留JavaScript的对象格式。一个典型的JSON如下:

    1. {
    2. "id": 1,
    3. "name": "Java核心技术",
    4. "author": {
    5. "firstName": "Abc",
    6. "lastName": "Xyz"
    7. },
    8. "isbn": "1234567",
    9. "tags": ["Java", "Network"]
    10. }
  • JSON作为数据传输的格式,有几个显著的优点:

    • JSON只允许使用UTF-8编码,不存在编码问题;
    • JSON只允许使用双引号作为key,特殊字符用\转义,格式简单;
    • 浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理。
  • 因此,JSON适合表示层次结构,因为它格式简单,仅支持以下几种数据类型:

    • 键值对:{“key”: value}
    • 数组:[1, 2, 3]
    • 字符串:”abc”
    • 数值(整数和浮点数):12.34
    • 布尔值:true或false
    • 空值:null

      Java使用json

      Jackson

  • jackson是用的比较广泛的序列化工具,同时是springboot默认自带的。其他知名的还Gson``Fastjson

    bean的序列化与反序列化

  1. ObjectMapper mapper = new ObjectMapper();
  2. //序列化
  3. String s=mapper.writeValueAsString(user);
  4. //反序列化
  5. User user=mapper.readValue(s, User.class);
  6. //还可以反序列化为map,貌似为<String,Object>
  7. Map map=mapper.readValue(ss, Map.class);
  8. //或者
  9. ...=mapper.readValue(s,"com.example.demo.dao.User")
  10. private static <T> Class<T> getType(String type) {
  11. try {
  12. return (Class<T>) Class.forName(type);
  13. } catch (ClassNotFoundException e) {
  14. throw new RuntimeException(e);
  15. }
  16. }

输入流的反序列化

待办 Main.class.getResourceAsStream(“/book.json”);

InputStream input = ...
ObjectMapper mapper = new ObjectMapper();
// 反序列化时忽略不存在的JavaBean属性,否则必须字段对应
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Book book = mapper.readValue(input, Book.class);

对时间进行序列化

  • jackson要序列化LocalDate等属性需要额外引入依赖,旧的时间api不清楚

    <dependency>
              <groupId>com.fasterxml.jackson.datatype</groupId>
              <artifactId>jackson-datatype-jsr310</artifactId>
          </dependency>
    
  • 然后创建时引入额外的功能模块 ```java ObjectMapper mapper=new ObjectMapper().registerModule(new JavaTimeModule());

//localdate属性序列化后为”time”:[2022,2,9]的形式

![image.png](https://cdn.nlark.com/yuque/0/2022/png/2319994/1644496389348-df725ace-7bbf-4032-95c8-bbf87370de16.png#clientId=u3037f794-387c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=284&id=u517b3195&margin=%5Bobject%20Object%5D&name=image.png&originHeight=652&originWidth=1927&originalType=binary&ratio=1&rotation=0&showTitle=false&size=672827&status=done&style=none&taskId=u5fd41132-ec09-4cbf-89e7-06cb2d83714&title=&width=838.9659863945578)
<a name="xqc0t"></a>
### 自定义反序列化规则
```json
{
    "name": "Java核心技术",
    "isbn": "978-7-111-54742-6"
}
public class Book {
    public String name;
    public BigInteger isbn;
}
//创建规则
public class IsbnDeserializer extends JsonDeserializer<BigInteger> {
    public BigInteger deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        // 读取原始的JSON字符串内容:
        String s = p.getValueAsString();
        if (s != null) {
            try {
                return new BigInteger(s.replace("-", ""));
            } catch (NumberFormatException e) {
                throw new JsonParseException(p, s, e);
            }
        }
        return null;
    }
}
//使用自定义规则
public class Book {
    public String name;
    // 表示反序列化isbn时使用自定义的IsbnDeserializer:
    @JsonDeserialize(using = IsbnDeserializer.class)  
    public BigInteger isbn;
}

Jackson规则

  • Jackson默认是区分大小写
  • 默认反序列化时如果字符串中存在属性,接收的对象不存在则报错
  • 命名规则默认好像是驼峰,但是实测并非如此。另外忽略大小写的优先级大于命名规则。所以如果配置了忽略大小写,则定义的命名规则不会生效

    注解定义

  • @JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE)置jackson大小写不敏感,用于类上

  • @JsonIgnore忽略该字段,正反都受影响
  • @JsonIgnoreProperties({“字段1”,“字段2”}) 用于类上,设置忽略多个字段,正反都受影响
    • 上面2个注解设置在字段上时是正反都影响,**jackson1.9前**我们可以设置在set/get方法避免都受影响。1.9后使用@JsonProperty(access=)指定只正/反
  • @JsonFormat(pattern = "yyyy-MM-dd" , timezone = "GMT+8")设置时间反序列化方式
  • @JsonProperty("?") 默认指定序列化与反序列化名称。可以指定序时才根据指定或者反时才…
    • @JsonProperty(value = "?",access = JsonProperty.Access.WRITE_ONLY)
    • @JsonProperty(value = "?",access = JsonProperty.Access.READ_ONLY)

      代码配置

      ```java ObjectMapper mapper=new ObjectMapper(); //大小写不敏感 mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); //忽略不存在的字段 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); //定义命名规则
       mapper.setPropertyNamingStrategy(PropertyNamingStrategy.?);
      

```

JSON 格式化后为 JavaScript 对象

JSON 格式在语法上与创建 JavaScript 对象代码是相同的。
由于它们很相似,所以 JavaScript 程序可以很容易的将 JSON 数据转换为 JavaScript 对象。
JSON - 图1

JSON - 图2 JSON - 图3JSON - 图4

JSON - 图5
通常我们从服务器中读取 JSON 数据,并在网页中显示数据

JSON - 图6,也可以认为是个json格式 的字符串
使用 JavaScript 内置函数 JSON.parse() 将字符串转换为 JavaScript 对象:
JSON - 图7