Java操作JSON

java操作json

一、简介

json : JavaScript Object Notation,JS 对象简谱。

官网: https://www.json.org/json-zh.html

二、使用场景

  • 网络传输

    描述同样的信息,json相比xml占用更少的空间,如:

    <?xml version="1.0" encoding="UTF-8"?>
    <person>
    	<id>1</id>
      <name>张三</name>
      <age>30</age>
    </person>
    

    json表示:

    {
      "id":1,
      "name":"张三",
      "age":30
    }
    
  • 序列化存储

三、java里面操作json有哪些技术?

  • 所谓的操作

    把java里面的bean、map、collection等转为json字符串(序列化)或反向操作(反序列化)。

  • java里操作json的技术一览

    image-20210816004456117

四、fastjson

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.73</version>
</dependency>

4.1 序列化(Bean->Json字符串)

JSON.toJSONString():转为JSON字符串

包含null

SerializerFeature.WriteMapNullValue:指定序列化时包含null

image-20220803184718798

String string = JSON.toJSONString(person, SerializerFeature.WriteMapNullValue);

image-20220803182537154

日期时间格式化

@JSONField(format = "yyyy-MM-dd HH:mm:ss")指定日期格式

@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private Date registerDate;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime birthDay;

奇怪的"$ref "引用探测

$ref:对象中多次引用了同一个其他对象的时候,序列化就会出现$ref

image-20220803181651795

可以通过SerializerFeature.DisableCircularReferenceDetect禁用引用探测功能

/**
     * 测试fastjson的引用探测
     * $ref:对象中多次引用了同一个其他对象的时候,序列化就会出现$ref
     */
@Test
public void test$Ref(){
    List<Person> list = new ArrayList<>();
    Person person = new Person();
    person.setId(33L);
    person.setName("乐之者java");
    list.add(person);
    list.add(person);
    list.add(person);
    // DisableCircularReferenceDetect 禁用引用探测功能
    String string = JSON.toJSONString(list,SerializerFeature.DisableCircularReferenceDetect);
    System.out.println(string);
}

SerializeFilter定制处理

对属性或属性值在序列化前做定制化处理

/**
     * SerializeFilter定制处理.要求:
     * 输出的json字符串的key是大写的、驼峰转下划线
     */
@Test
public void testSerializeFilter(){
    Person person = new Person();
    person.setId(1L);
    //        person.setName("乐之者java");
    person.setPwd("123");
    person.setAddr("河南");
    person.setWebsiteUrl("http://www.roadjava.com");
    person.setRegisterDate(new Date());
    person.setBirthDay(LocalDateTime.now());
    /*
        object: person对象
        name:属性
        value: name属性对应的值
         */
    NameFilter nameFilter = (object,name, value) -> name.toUpperCase();
    String string = JSON.toJSONString(person,nameFilter);
    System.out.println(string);
}

image-20220803182837776

美化输出

将第二个参数设为true

建议:在网络传输中最好不要进行美化输出

image-20220803185949552

4.2 反序列化(Json字符串->Bean)

  • 泛型处理

    fastjson对于json中多的key默认的处理就是忽略

后端向前端返回json数据,设置统一返回结果

@Data
public class ResultVO<T> {
    private Boolean success = Boolean.TRUE;
    private T data;
    private ResultVO(){}

    public static <T> ResultVO<T> buildSuccess(T t) {
        ResultVO<T> resultVO = new ResultVO<>();
        resultVO.setData(t);
        return resultVO;
    }
}

测试反序列化

反序列化后不能够获取到泛型类型

/**
     * 测试反序列化
     * json字符串-->bean
     */
@Test
public void testDeSerialize(){
    String jsonStr = "{\"address\":\"河南\",\"birthDay\":\"2021-08-17 03:38:09\",\"id\":1,\"name\":null,\"pwd\":\"123\",\"registerDate\":\"2021-08-17 03:38:09\",\"websiteUrl\":\"http://www.roadjava.com\"}";
    
    // 反序列化为person对象
    Person person = JSON.parseObject(jsonStr, Person.class);
    System.out.println(person);
    
    // 返回给调用端ResultVO
    ResultVO<Person> personResultVO = ResultVO.buildSuccess(person);
    String voJsonStr = JSON.toJSONString(personResultVO);
    
    // 调用端需要把voJsonStr反序列化为对象
    // 反序列化后不能够获取到泛型类型
    //        ResultVO resultVO = JSON.parseObject(voJsonStr, ResultVO.class);
    //        System.out.println("resultVO"+resultVO);
    //        Object data = resultVO.getData();

    // 需要反序列化为什么类型,就给TypeReference传入什么类型即可
    ResultVO<Person> deSerializedVo = JSON.parseObject(voJsonStr, new TypeReference<ResultVO<Person>>() {});
    System.out.println("deSerializedVo:"+deSerializedVo);
    Person data = deSerializedVo.getData();
    System.out.println("data:"+data);
}

4.3 通用配置

指定属性名和json字符串key的对应关系

/**
     * 地址
     * name = "address":指定属性名和json字符串key的对应关系 addr---address
     */
@JSONField(name = "address")
private String addr;

image-20220803190241256

反序列化时传入的是addr,在已经通过配置了@JSONField(name = "address")的情况下,是不能对该属性进行反序列化的,只能将其改为address才能对该属性进行反序列化

image-20220803190843328

忽略指定属性

例如不想将密码返回给前端

@JSONField(serialize = false,deserialize = false)
private String pwd;

五、jackson

Springmvc默认使用jackson

<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.10.1</version>
</dependency>
<!--对LocalDateTime等jdk8时间日期api的转化支持-->
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
  <version>2.10.1</version>
</dependency>

5.1 序列化

  • 只包含非null属性
    • 全局配置
    • 单个的bean配置
  • 日期时间格式化
    • 全局配置
    • 单个bean的配置
  • 美化输出

5.2 反序列化

  • 忽略不存在的key
  • 泛型处理

5.3 通用配置

  • 序列化: 驼峰转下划线/反序列化:下划线转驼峰
  • 指定属性名和json字符串key的对应关系
  • 忽略指定属性

5.4 其他应用

  • 对象更新
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

懿所思

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值