【学习笔记】JSON小知识

我是灼灼,一只初学Java的大一金渐层。
向往余秀华和狄兰·托马斯的疯狂,时常沉溺于将情感以诗相寄;追逐过王尔德、王小波的文字,后陷于毛姆和斯蒂芬·金不可自拔;热爱文学的浪潮,白日梦到底却总在现实里清醒;艳羡平静又极度渴盼奔跑的力量。
欢迎与我交流鸭· QQ:1517526827;
个人博客:https://blog.csdn.net/weixin_52777510?spm=1001.2101.3001.5343

使用JSON

内容来自廖雪峰官方Java教程:使用JSON~

XML数据格式的特点是功能全面,但标签繁琐,格式复杂。在Web上使用XML现在越来越少,取而代之的是JSON这种数据结构

JSON是JavaScript Object
Notation的缩写,它去除了所有JavaScript执行代码,只保留JavaScript的对象格式

一个典型的JSON
{
    
    
    "id": 1,
    "name": "Java核心技术",
    "author": {
    
    
        "firstName": "Abc",
        "lastName": "Xyz"
    },
    "isbn": "1234567",
    "tags": ["Java", "Network"]
}

JSON作为数据传输的格式,有几个显著的优点:

  • JSON只允许使用UTF-8编码,不存在编码问题;
  • JSON只允许使用双引号作为key,特殊字符用\转义,格式简单;
  • 浏览器内置JSON支持,如果把数据用JSON发送给浏览器,可以用JavaScript直接处理

JSON适合表示层次结构,由于格式简单,仅支持以下几种数据类型:

  • 键值对:{"key": value}
  • 数组:[1, 2, 3]
  • 字符串:"abc"
  • 数值(整数和浮点数):12.34
  • 布尔值:truefalse
  • 空值:null
直接使用JavaScript对JSON进行读写

浏览器支持

// JSON string to JavaScript object:
jsObj = JSON.parse(jsonStr);

// JavaScript object to JSON string:
jsonStr = JSON.stringify(jsObj);

开发Web应用的时候,使用JSON作为数据传输,在浏览器端非常方便。因为JSON天生适合JavaScript处理,所以,绝大多数REST API都选择JSON作为数据传输格式

使用Java对JSON进行读写(反序列化)

在Java中,针对JSON也有标准的JSR 353 API,但是如果能直接在XML和JavaBean之间互相转换是最好的。类似的,如果能直接在JSON和JavaBean之间转换,那么用起来就简单多了。

常用的用于解析JSON的第三方库有:

  • Jackson
  • Gson
  • Fastjson

以Jackson为例,只需要引入Maven依赖:

  • com.fasterxml.jackson.core:jackson-databind:2.10.0

就可以使用下面的代码解析一个JSON文件

InputStream input = Main.class.getResourceAsStream("/book.json");
ObjectMapper mapper = new ObjectMapper();
// 反序列化时忽略不存在的JavaBean属性:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Book book = mapper.readValue(input, Book.class);

核心代码是创建一个ObjectMapper对象

关闭DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES功能使得解析时如果JavaBean不存在该属性时解析不会报错

把JSON解析为JavaBean的过程称为反序列化。如果把JavaBean变为JSON,那就是序列化。

JavaBean到JSON的序列化
String json = mapper.writeValueAsString(book);
把JSON的某些值解析为特定的Java对象

例如LocalDate

{
    
    
    "name": "Java核心技术",
    "pubDate": "2016-09-01"
}

要解析为:

public class Book {
    
    
    public String name;
    public LocalDate pubDate;
}

需要引入标准的JSR 310关于JavaTime的数据格式定义至Maven:

  • com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.10.0

在创建ObjectMapper时,注册一个新的JavaTimeModule

ObjectMapper mapper = new ObjectMapper().registerModule(new JavaTimeModule());

有时,内置的解析规则和扩展的解析规则如果都不满足需求,还可以——

自定义解析(自定义反序列化)

举个例子,假设Book类的isbn是一个BigInteger

public class Book {
    
    
	public String name;
	public BigInteger isbn;
}

但JSON数据并不是标准的整型格式

{
    
    
    "name": "Java核心技术",
    "isbn": "978-7-111-54742-6"
}

直接解析会报错。这时需要自定义一个IsbnDeserializer,用于解析含有非数字的字符串

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

Book类中使用注解标注:

public class Book {
    
    
    public String name;
    // 表示反序列化isbn时使用自定义的IsbnDeserializer:
    @JsonDeserialize(using = IsbnDeserializer.class)
    public BigInteger isbn;
}

自定义序列化时需要自定义一个IsbnSerializer,然后在Book类中标注@JsonSerialize(using = ...)

小结

JSON是轻量级的数据表示方式,常用于Web应用

Jackson可以实现JavaBean和JSON之间的转换

可以通过Module扩展Jackson能处理的数据类型;

可以自定义JsonSerializerJsonDeserializer来定制序列化和反序列化。


在这里插入图片描述
如果对你有帮助的话不要忘记一键三连噢~
谢谢鸭~

初次编写于2021/2/23日;

猜你喜欢

转载自blog.csdn.net/weixin_52777510/article/details/113988015
今日推荐