SuperAPI AI Directory

jackson-patterns

General & other

View repository

Updated 10-15 21:48

About this skill

Jackson JSON Serialization

Codify Jackson usage rules. LLM default configuration SerializationFeature.WRITE_DATES_AS_TIMESTAMPS=true, but Chinese developers expect yyyy-MM-dd HH:mm:ss.

Capability Boundaries

✅ Strong Suits

  1. Date Format — yyyy-MM-dd HH:mm:ss (non-ISO-8601), integrated with Spring Boot
  2. Null Serialization — array→[]/string→""/number→null/boolean→null (rules must be explicit if inconsistent)
  3. @JsonView — the same object returns different fields in different scenarios (list vs detail)
  4. TypeReference — correctly deserialize generic types (List, etc.)
  5. @JsonProperty/@JsonFormat/@JsonIgnore — field renaming/formatting/ignoring

❌ Out of Scope

  1. Java Bean mapping → MapStruct(generated at compile time, Jackson is serialization not mapping)
  2. JSON is the API format, use MapStruct for internal object mapping

Errors LLMs most commonly make

# Mistake Correct Approach
1 Date serialized as timestamp 1702468800000 Configure WRITE_DATES_AS_TIMESTAMPS=false, format yyyy-MM-dd HH:mm:ss
2 null fields not returned or returned as null Explicit rules: array→[], string→"", number→null, boolean→null
3 new ObjectMapper() every time ObjectMapper is thread-safe, use an application-level singleton
4 objectMapper.readValue(json, List.class) objectMapper.readValue(json, new TypeReference<List<User>>(){})
5 Standard JSON format not aligned with other systems NullNode/WRITE_BIGDECIMAL_AS_PLAIN, etc. require explicit configuration

Core Rules Quick Reference

// ✅ Spring Boot 配置(ObjectMapper全局)
@Configuration
public class JacksonConfig {
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer customizer() {
        return builder -> builder
            .simpleDateFormat("yyyy-MM-dd HH:mm:ss")
            .serializationInclusion(JsonInclude.Include.NON_NULL)
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
    }
}

// ✅ 注解方式
@Data
public class UserVO {
    @JsonProperty("user_name")   // JSON字段重命名
    private String username;

    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;

    @JsonIgnore                  // 序列化时忽略
    private String password;

    @JsonView(Views.Detail.class) // 仅详情视图返回
    private String email;
}

// ✅ TypeReference 反序列化
List<User> users = objectMapper.readValue(json,
    new TypeReference<List<User>>(){});

// ✅ Null值处理规则
objectMapper.configOverride(String.class)
    .setInclude(JsonInclude.Value.construct(
        JsonInclude.Include.NON_NULL,  // null string → null
        JsonInclude.Include.NON_NULL
    ));

Gotchas

  1. ObjectMapper is thread-safe — don't new it every time, use a singleton
  2. TypeReference is essential — generic deserialization without TypeReference yields a LinkedHashMap
  3. @JsonProperty only affects serialization — does not affect the Java field name
  4. WRITE_DATES_AS_TIMESTAMPS defaults to true — Spring Boot changes the default to false
  5. Jackson's @JsonFormat and Spring's @DateTimeFormat are different — the former for JSON, the latter for form/Query parameters
  6. Cannot deserialize LocalDateTime by default — requires the jackson-datatype-jsr310 dependency
  7. Difference between @JsonIgnore and @JsonProperty(access=READ_ONLY) — @JsonIgnore ignores both directions, access controls the direction
  8. A null number does not automatically become 0 — requires a global include=NON_NULL or individual configuration

Data Privacy

This skill does not collect, store, or transmit any user data.