jackson学习

733 阅读2分钟

jackson 序列化问题

jackson序列化对象时,需要对象拥有空构造方法,否则无法序列化,同时jackson序列化化时,是将getXX()方法的XX进行序列化和反序列,如果有方法是getXX(),但是没有对应的字段属性或者对应的set方法,请添加如下注解,对列表里的属性在序列化和反序列时忽略

@JsonIgnoreProperties(value = {"serviceKey", "serviceNodeKey", "serviceAddress"})
public class test{
//...
}

序列化LocalDateTime不支持

如果需要jackson支持序列化LocalDateTime,则需要引入如下依赖,并将time的模块支持注册到ObjectMapper,但是这样序列化后的时间会出现如[XX,XX,XX]这样的格式,这时我们需要在对应的字段上加上如下注解

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")//指定序列化格式,和时区

依赖

1.  <dependency>
1.  <groupId>com.fasterxml.jackson.datatype</groupId>
1.  <artifactId>jackson-datatype-jsr310</artifactId>
1.  <version>2.13.0</version> <!-- 版本保持一致 -->
1.  </dependency>

配置更改

/**
 * 定义jackson对象
 */
private static final ObjectMapper MAPPER = new ObjectMapper();

static {
    // 添加对time模块的全部支持==>LocalDateTime
    MAPPER.registerModule(new JavaTimeModule());
}

序列化支持首字母大写

通过@JsonAutoDetect注解添加字段可见范围和get以及set可见范围实现

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY, getterVisibility = JsonAutoDetect.Visibility.NONE)

image.png

ObjectMapper配置支持

通过configure或者序列化器等配置给mapper实现增强, Jackson 中的 JSON 中的 Configure() 方法 | w3cschool笔记

// 遇到未知属性,即未拥有set时,忽视报错
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 忽略值为null的序列化
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
// 开启整数反序列化时使用长整型(long)的选项。确保处理的数据不会因类型限制丢失信息
mapper.configure(DeserializationFeature.USE_LONG_FOR_INTS, true);
//开启输出缩进功能。这通常用于美化JSON格式输出,使结构更清晰易读
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

JsonNode

JsonNode是jackson内置的类,将json转化成JsonNode树,其内部是map结构,key与value的JsonNode形成映射关系

通过ObjectMapper的readTree方法将Json转至JsonNode

JsonNode内部含有判断方法,如判断当前jsonNode的值是否为对象或者数组等

用途:可以用于检验json是否合法或者获取json中某个值

package com.think.load.common.util;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.think.load.strategy.JsonValidationStrategy;
import org.springframework.util.StringUtils;

import java.util.Iterator;

public class JsonJoinUtil {
  private static final String SEPARATOR = ",";
  private static final String NEW_LINE = "\n";
  private static final String INDENT = "  ";
  private static final String EQUAL_SIGN = "=";

  public static String joinByEqualSign(String json) {
    StringBuilder result = new StringBuilder();
    // 校验是否是合法json
    if (JsonValidationStrategy.getInstance().validate(json)) {
      ObjectMapper mapper = JsonValidationStrategy.getMapper();
      try {
        // 将json读取成树
        JsonNode jsonNode = mapper.readTree(json);
        // 判断是否为对象
        if (jsonNode.isObject()) {
          // 获取key名称的迭代器
          Iterator<String> stringIterator = jsonNode.fieldNames();
          while (stringIterator.hasNext()) 
            // 获取下一个key的值
            String key = stringIterator.next();
            //根据key从map中获取值value的JsonNode
            JsonNode value = jsonNode.get(key);
            // 通过value.toString()获取值
            result
                .append(key)
                .append(EQUAL_SIGN)
                .append(joinByEqualSign(value.toString().replace(""", "")))
                .append(NEW_LINE);
          }
          return result.toString();
        }
        // 判断是否为数组
        if (jsonNode.isArray()) {
          for (JsonNode arrayElement : jsonNode) {
            result.append(joinByEqualSign(arrayElement.toString()));
          }
          return result.toString();
        }
      } catch (JsonProcessingException e) {
        return replaceBracket(json);
      }
    }
    return replaceBracket(json);
  }

  private static String replaceBracket(String value) {
    if (!StringUtils.hasLength(value)) return value;
    // replace去除[和]
    return value.replaceAll("\[", "").replaceAll("]", "");
  }
}