美文网首页
SpringBoot中JSON数据处理及Jackson库详解

SpringBoot中JSON数据处理及Jackson库详解

作者: liushiping | 来源:发表于2023-06-07 17:21 被阅读0次

    一、序列化和反序列化

    在SpringMVC中,前、后端之间数据传输会涉及到数据的序列化和反序列化操作。当注解为@ResponseBody时,请求响应默认使用的序列化方式是JSON,而SpringBoot默认是使用Jackson作为JSON数据格式处理的类库。

    • 序列化:按照指定的格式、顺序等将实体类对象转换为JSON对象;
    • 反序列化:将JSON对象中的字符串、数字,将其转换为包含Date类型、Integer等类型的实体对象;

    二、在Spring中使用Jackson

    Jackson提供了注解和手动数据转换两种方式,帮助我们进行序列化和反序列化工作。

    2.1常用注解

    注解通常用于标注java实体类或实体类的属性。

    • @JsonPropertyOrder(value={"pname1","pname2"}) 改变子属性在JSON序列化中的默认定义的顺序。如:param1在先,param2在后。
    • @JsonIgnore 加在属性上面,排除某个属性不做序列化与反序列化
    • @JsonIgnoreProperties(ignoreUnknown = true),将这个注解写在类上之后,就会忽略JSON字符串中存在,但实体类不存在的属性,不予赋值,也不会出现异常。
    • @JsonIgnoreProperties({ "xxx", "yyyy" }) 忽略某些属性不进行序列化
    • @JsonProperty(anotherName) 为某个属性换一个名称,体现在JSON数据里面
    • @JsonInclude(JsonInclude.Include.NON_NULL) 排除为空的元素不做序列化反序列化
    • @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 指定日期类型的属性格式
    //因为定义了JsonPropertyOrder,content在先,title在后
    @JsonPropertyOrder(value={"content","title"})  
    public class Article {
        //因为定义了JsonIgnore,id属性被忽略
        @JsonIgnore 
        private Long id;
    
        //因为定义了JsonProperty,author属性变为authorName
        @JsonProperty("authorName")  
        private String author;
        private String title;
        private String content;
    
         //因为定义了JsonInclude和JsonFormat,createTime不能为空,并且格式为 "yyyy-MM-dd HH:mm:ss"
        @JsonInclude(JsonInclude.Include.NON_NULL)
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
        private Date createTime;
        private List<Reader> reader;
    }
    

    上文代码中对应的JSON数据格式可以为:

    {
        authorName:"",
        content:"",
        title:"",
        createTime:"2023-06-08 17:12:12",
        reader:[{"name":"William","age":26},{"name":"Jerry","age":37}]
    }
    

    通常会对日期类型转换,进行全局配置,而不是在每一个java bean里面配置

    spring: 
        jackson:
            date-format: yyyy-MM-dd HH:mm:ss
            time-zone: GMT+8
    

    2.2手动数据转换

    除了在spring框架内实现自动的前后端JSON数据与java对象的转换,我们还可以使用jackson自己写代码进行转换。

    //jackson的ObjectMapper 转换对象
    ObjectMapper mapper = new ObjectMapper();
    //将某个java对象转换为JSON字符串
    String jsonStr = mapper.writeValueAsString(javaObj);
    //将jsonStr转换为Article类的对象
    Article article = mapper.readValue(jsonStr, Article.class);
    

    当JSON字符串代表的对象的字段多于类定义的字段时,使用readValue会抛出UnrecognizedPropertyException异常,在类的定义处加上@JsonIgnoreProperties(ignoreUnknown = true)可以解决这个问题。

    三、Jackson全局配置

    在Spring框架内使用Jackson的时候,通常需要一些特殊的全局配置,来应对我们JSON序列化与反序列化中出现的各种问题。Spring Boot 提供了两种配置方式:配置文件的方式和代码的方式。配置文件的方式更容易,单代码的方式二更灵活。当配置文件的方式无法解决的问题,可以尝试使用代码的方式进行配置。

    2.1配置文件的方式

    spring:
      jackson:
        #日期类型格式化
        date-format: yyyy-MM-dd HH:mm:ss
        serialization:
          #格式化输出,通常为了节省网络流量设置为false。因为格式化之后会带有缩进,方便阅读。
          indent_output: false
          #某些类对象无法序列化的时候,是否报错
          fail_on_empty_beans: false
        #设置空如何序列化,见下文代码方式详解
        defaultPropertyInclusion: NON_EMPTY
        deserialization:
          #json对象中有不存在的属性时候,是否报错
          fail_on_unknown_properties: false
        parser:
          #允许出现特殊字符和转义符
          allow_unquoted_control_chars: true
          #允许出现单引号
          allow_single_quotes: true
    

    2.2代码的方式

    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
            ObjectMapper objectMapper = builder.createXmlMapper(false).build();
    
            // 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
            // Include.Include.ALWAYS 默认
            // Include.NON_DEFAULT 属性为默认值不序列化
            // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
            // Include.NON_NULL 属性为NULL 不序列化
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            // 允许出现特殊字符和转义符
            objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
            // 允许出现单引号
            objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
            // 字段保留,将null值转为""
            objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){
                @Override
                public void serialize(Object o, JsonGenerator jsonGenerator,
                                      SerializerProvider serializerProvider)throws IOException {
                    jsonGenerator.writeString("");
                }
            });
            return objectMapper;
    }
    

    相关文章

      网友评论

          本文标题:SpringBoot中JSON数据处理及Jackson库详解

          本文链接:https://www.haomeiwen.com/subject/meznedtx.html