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

2023-06-07  本文已影响0人  liushiping

一、序列化和反序列化

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

二、在Spring中使用Jackson

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

2.1常用注解

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

//因为定义了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;
}
上一篇 下一篇

猜你喜欢

热点阅读