springboot中Json常用注解的使用以及通过@JsonComponent实现json序列化和返序列化操作

623 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第9天,点击查看活动详情

一、Json开发

Spring Boot提供了与三个JSON映射库的集成:

  • Gson
  • Jackson 性能最好
  • JSON-B

如下可以看到 image.png

Jackson 是我们使用的默认json库。

1-1、jackson的使用

  • @JsonIgnore
    • 进行排除json序列化,将它标注在属性上将不会进行json序列化
  • @JsonFormat(pattern = "yyyy-MM-dd hh:mm:ss",locale = "zh")
    • 进行日期格式化
  • @JsonInclude(JsonInclude.Include.NON_NULL)
    • 当属性值为null时则不进行json序列化
  • @JsonProperty("uname")
    • 来设置别名

1-1-1、jackjson注解用法

下面来演示一下这几个注解的用法,在未使用注解的情况下调用接口

image.png

给user添加注解

image.png 再次访问接口看下效果

image.png

将张三的address值删掉,再次看下结果

image.png

可以看到地址已经不显示了 image.png

1-1-2、使用@JsonComponent来根据自己的业务需求进行json的序列化和反序列化

有些场景

  1. 一次查不出完整的数据返回给客户端, 需要根据需求去做一些个性化调整
  2. 根据不同的权限给他返回不同的序列化数据 比如当用户是某个角色,我们就可以设置一些不同的属性

比如我们针对User进行序列化和反序列操作

package com.jony.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.*;
import com.jony.entity.User;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.boot.jackson.JsonObjectDeserializer;
import org.springframework.boot.jackson.JsonObjectSerializer;

import java.io.IOException;


@JsonComponent
public class UserJsonCustom {
    public static class Serializer extends JsonObjectSerializer<User> {

        @Override
        protected void serializeObject(User user, JsonGenerator jgen, SerializerProvider provider) throws IOException {
            jgen.writeObjectField("id", user.getId());   //{"id","xxx"}
            jgen.writeObjectField("uname", "xxxxx");
            /*jgen.writeFieldName("");  单独写key
            jgen.writeObject();   单独写value
            */
      
        }
    }

    public static class Deserializer extends JsonObjectDeserializer<User> {

        @Override
        protected User deserializeObject(JsonParser jsonParser, DeserializationContext context, ObjectCodec codec, JsonNode tree) throws IOException {
            User user = new User();
            user.setId(tree.findValue("id").asInt());

            return user;
        }
    }
}

1-1-2-1、序列化

public static class Serializer extends JsonObjectSerializer<User> {

    @Override
    protected void serializeObject(User user, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        jgen.writeObjectField("id", user.getId());   //{"id","xxx"}
        jgen.writeObjectField("uname", "xxxxx");
        /*jgen.writeFieldName("");  单独写key
        jgen.writeObject();   单独写value
        */
    
    }
}

序列化中,可以通过writeObjectField设置对应的key和value,此时可以自由定制User返回Json的key和value,同时也可以分别使用writeFieldName设置key使用writeObject设置value

此时再次访问一下接口,可以看到前端看到的数据已经是我们通过序列处理的数据。

image.png

1-1-2-1-1、序列化基类

首先进入JsonObjectSerializer这个父类 image.png

可以看到他帮助我们实现了开始写->序列化操作->结束写 的过程。这样就不用我们自己去实现了 image.png

1-1-2-2、范序列化

我们可以通过tree.findValue("xx").asInt()/asString()等就可以获得对象中的值了。 image.png

然后我们通过之前的mockMvc进行测试一下,可以看到我们提交的数据,到最终输出只有id进行了保存。证明我们返序列化操作执行成功。

image.png

1-1-2-2-1、反序列化基类

首先进入这个范序列继承的基类JsonObjectDeserializer image.png

他帮助我们先获取Json的code->然后读取到JsonNode中->反序列操作 image.png