SuperAPI AI Directory

ddd4j-jackson

Data & analytics

View repository

Updated 10-16 05:47

About this skill

DDD4J Jackson serialization rules

Encode the usage rules of Jackson in DDD4J projects. Jackson usage in LLM training data conflicts with project conventions.

Why this skill is needed

LLMs will serialize dates in ISO-8601 format 2024-03-15T10:30:00Z —DDD4J requires 2024-03-15 10:30:00. LLMs will not return []for null arrays—the DDD4J frontend expects null arrays to never appear. LLMs do not know these rules.

Capability Boundaries

✅ Strong Suits

  1. Date format rule — yyyy-MM-dd HH:mm:ss (non-ISO-8601)
  2. Null value rules — array→[], string→"", number→keep null, boolean→keep null
  3. @Sensitive masking — 5 strategies (phone/ID card/name/address/email)
  4. JacksonKit — independent ObjectMapper dedicated to Redis/cache (DefaultTyping.NON_FINAL)
  5. ToLongDeserializer — handles precision loss for large numbers in frontend JS

❌ Out of Scope

  1. Entity inheritance/return value conventions → ddd4j-core
  2. MyBatis JSON field handling → ddd4j-mybatis
  3. API signature/security → ddd4j-satoken

The most common LLM mistakes

# Wrong Correct approach
1 Use ISO-8601 for dates 2024-03-15T10:30:00Z Use yyyy-MM-dd HH:mm:ss
2 null array returns null Return []
3 null string returns null Return ""
4 Return 0 for a null number: numbers/booleans keep null, no conversion
5 Write masking logic manually Use @Sensitive(strategy = SensitiveStrategy.PHONE)
6 Use Web ObjectMapper for cache Use JacksonKit (DefaultTyping.NON_FINAL + ALL visibility)
7 Return Long directly for large numbers Use ToLongDeserializer to handle precision loss

Core rules quick reference

// ❌ 错误:LLM会这样写
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime createTime;

// ✅ 正确:DDD4J 已全局配置
private LocalDateTime createTime;  // 序列化为 "2024-03-15 10:30:00"

// ✅ Null 处理:前端收到的 JSON
// null 数组 → []      (默认开启)
// null 字符串 → ""    (默认开启)
// null 对象 → {}      (默认开启)
// null 数字 → null    (不转化)
// null 布尔 → null    (不转化)

// ✅ 敏感数据脱敏
public class UserVO {
    @Sensitive(strategy = SensitiveStrategy.PHONE)
    private String phone;    // 185****1653
    @Sensitive(strategy = SensitiveStrategy.ID_CARD)
    private String idCard;   // 1234****5678
    @Sensitive(strategy = SensitiveStrategy.USERNAME)
    private String name;     // 张*三
    @Sensitive(strategy = SensitiveStrategy.EMAIL)
    private String email;    // r*****o@qq.com
    @Sensitive(strategy = SensitiveStrategy.ADDRESS)
    private String address;  // 北京市****海淀区****
}

// ✅ 两个 ObjectMapper
// Web用:JacksonAutoConfiguration 自动配置的,用于 HTTP 请求响应
@Autowired private ObjectMapper objectMapper;
// 缓存用:JacksonKit 独立 ObjectMapper,带 DefaultTyping.NON_FINAL
JacksonKit.toJson(obj);    // 序列化时写入类型信息
JacksonKit.fromJson(json, Type.class);  // 反序列化时根据类型信息恢复

Gotchas

  1. Do not configure Jackson2ObjectMapperBuilderCustomizer yourself — DDD4J is already preconfigured; conflicts will cause date format corruption
  2. Storing objects in Redis must use JacksonKit, not ObjectMapper — Web ObjectMapper has no DefaultTyping, polymorphic deserialization will lose types
  3. A null number will not be converted to 0 — the frontend needs to handle the case where a number may be null (unlike arrays/strings)
  4. @Sensitive only takes effect on String type — other types are ignored
  5. ToLongDeserializer accepts strings and converts them to Long — the frontend passes "1234567890123456789" and it can still be parsed correctly
  6. The date format affects both serialization and deserialization — dates submitted by the frontend must also be yyyy-MM-dd HH:mm:ss

Data Privacy

This skill does not collect, store, or transmit any user data. The @Sensitive annotation is only used to mask existing sensitive data during serialization.