Java对象为啥要实现Serializable接口?

  • 实现Serializable: 保持序列化和反序列化对象的一致性
  • Serializing private variables in java? private成员变量可以被序列化
  • 父类实现接口后,所有派生类的属性都会被序列化。子类实现接口的话,父类的属性值丢失。

    JSON库

    jackson库

    配置

    1. public final class JsonUtils {
    2. private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
    3. private static final TypeReference<HashMap<String, Object>> HASH_MAP_TYPE = new TypeReference<HashMap<String, Object>>() {
    4. };
    5. private static final TypeReference<ArrayList<Object>> LIST_TYPE = new TypeReference<ArrayList<Object>>() {
    6. };
    7. private static final ObjectMapper mapper = new ObjectMapper();
    8. static {
    9. mapper.configure(Feature.ALLOW_SINGLE_QUOTES, true);
    10. mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
    11. mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    12. mapper.setSerializationInclusion(Include.NON_NULL);
    13. }
    14. }

    创建JsonNode

    1. ArrayNode labels = JsonNodeFactory.instance.arrayNode()

    JsonNode的asText和toString方法区别

    String => List

    注意:TypeReference中如果是抽象类,需要定义@JsonTypeInfo

    1. String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
    2. ObjectMapper objectMapper = new ObjectMapper();
    3. List<Car> cars1 = objectMapper.readValue(jsonArray, new TypeReference<List<Car>>(){});

    Object => String

    ```java mapper.writeValueAsString(object)

mapper.writerFor(type).writeValueAsString(object)

  1. <a name="aB1rL"></a>
  2. ## @JsonTypeInfo多态处理
  3. [@JsonTypeInfo 多态类型处理](https://www.jianshu.com/p/a21f1633d79c)
  4. ```java
  5. @JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS)
  6. @JsonSubTypes({
  7. @JsonSubTypes.Type(value = GeneralOrderItem.class),
  8. @JsonSubTypes.Type(value = QuantityOrderItem.class),
  9. @JsonSubTypes.Type(value = SitesOrderItem.class),
  10. })
  11. public abstract class BaseOrderItem implements Serializable {
  12. private static final long serialVersionUID = 9038806540511318608L;
  13. private DeepdrawService.Type serviceType;
  14. }

注意,Collection类型要使@JsonTypeInfo生效,必须使用mapper.writeFor(type) => Github-issue

  1. @Test
  2. public void toTypedJson_happyPath() {
  3. SitesOrderItem item = new SitesOrderItem();
  4. item.setServiceType(Type.DISTRIBUTION);
  5. List<SitesOrderItem> items = Arrays.asList(item);
  6. assertThat(JsonUtils.toJson(items, new TypeReference<List<BaseOrderItem>>() {
  7. }), is("[{\"@c\":\".SitesOrderItem\",\"serviceType\":\"DISTRIBUTION\"}]"));
  8. }
  1. public static String toJson(Object object, TypeReference<?> type) {
  2. try {
  3. return mapper.writerFor(type).writeValueAsString(object);
  4. } catch (JsonProcessingException var3) {
  5. logger.error("Cannot format json : " + object, var3);
  6. return "{}";
  7. }
  8. }

LocalDate的序列化和反序列化

jackson-modules-java8
注意只能用2.9及以下,以上报错

  1. compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: '2.9.9'
  2. compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: '2.9.9'
  3. compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.9.9'

文档
另一种方法

Transient关键字

注解类 描述 场景
1 JsonIgnoreProperties 用于标记忽略一个或多个属性。可以注解在类上、构造函数、方法、字段上。 oneToMany, ManyToMany
字段防止死循环
2 JsonIgnore @JsonIgnore注解用于在字段级别标记要忽略的属性。注意:系列化和反系列化时都会被忽略。 敏感字段
3 JsonInclude 使用@JsonInclude可以只包含非空的属性,也即排除值为empty、null的属性。
4 JsonAutoDetect 默认情况下,jackson获取public权限的字段进行序列化和反序列化。如果没有public修饰的字段,就会去获取public修饰的getter/setter。使用 JsonAutoDetect注解,我们就可以修改默认的行为。

问题

  • "[{}, {}]"读取后得到的arraynode进行遍历,每项是个空的ObjectNode,.path(“xxx”)得到missingNode
  • 属性不要is开头