50% 的 Java 程序员都不知道的 Jackson 高级用法!

50% 的 Java 程序员都不知道的 Jackson 高级用法!

Jackson 是目前 Java 生态中使用最广泛的 JSON 序列化/反序列化库,但绝大多数人只用到了它的最基础功能(@JsonPropertyObjectMapper.readValue 等),其实它还有非常多强大且实用的高级特性,能大幅提升代码质量、性能和可维护性。

下面列出 10 个非常实用但使用率明显偏低的 Jackson 高级用法(2025–2026 视角),很多都是中高级开发者和架构师才会主动用到的。

1. @JsonAnyGetter + @JsonAnySetter(动态字段)

当 JSON 中有大量不确定字段,或者你想把 Map 字段“打平”到对象里时非常有用。

public class DynamicUser {
    private String name;
    private Map<String, Object> extra = new LinkedHashMap<>();

    @JsonAnyGetter
    public Map<String, Object> getExtra() {
        return extra;
    }

    @JsonAnySetter
    public void setExtra(String key, Object value) {
        extra.put(key, value);
    }
}

效果
输入 JSON:{"name":"张三", "age":18, "city":"北京"}
对象中 extra 会自动包含 agecity,而不需要提前定义所有字段。

2. @JsonUnwrapped(打平嵌套对象)

public class Address {
    private String city;
    private String street;
}

public class Person {
    private String name;

    @JsonUnwrapped
    private Address address;
}

序列化后

{
  "name": "李四",
  "city": "上海",
  "street": "南京路"
}

非常适合把嵌套对象“展平”到顶层,常见于 DTO 与数据库实体转换。

3. @JsonInclude + @JsonInclude.Include.NON_EMPTY / NON_DEFAULT

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class UserDTO {
    private String name;
    private String email;           // null 不输出
    private Integer age = 0;        // 0 不输出(NON_EMPTY 对数字无效)
    private List<String> roles = Collections.emptyList(); // 空集合不输出
}

常用变体

  • NON_NULL:null 不输出(最常见)
  • NON_EMPTY:空集合、空字符串、空 Map 不输出
  • NON_DEFAULT:默认值不输出(boolean false、int 0 等)

4. @JsonProperty.Access(读写控制)

public class User {
    @JsonProperty(access = JsonProperty.Access.READ_ONLY)
    private Long id;                // 只读,序列化有,反序列化忽略

    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    private String password;        // 只写,反序列化有,序列化忽略

    @JsonProperty(access = JsonProperty.Access.AUTO) // 默认
    private String username;
}

常用于:隐藏敏感字段、保护 id 不被前端修改等。

5. @JsonNaming(统一命名策略)

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public class UserInfo {
    private String firstName;
    private String lastLoginTime;
}

输出

{
  "first_name": "张",
  "last_login_time": "2025-12-01"
}

支持的策略:

  • SnakeCaseStrategy(snake_case)
  • KebabCaseStrategy(kebab-case)
  • UpperCamelCaseStrategy(UpperCamelCase)
  • LowerCaseStrategy(全小写)

6. @JsonView(视图控制,按需返回字段)

public class Views {
    public static class Public {}
    public static class Internal extends Public {}
}

public class User {
    @JsonView(Views.Public.class)
    private String username;

    @JsonView(Views.Internal.class)
    private String password;

    @JsonView(Views.Internal.class)
    private String phone;
}

使用

ObjectMapper mapper = new ObjectMapper();
mapper.writerWithView(Views.Public.class).writeValueAsString(user);
// 只输出 username

非常适合不同接口返回不同字段集的场景(用户列表 vs 用户详情)。

7. @JsonFormat(自定义日期格式)

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime createTime;

支持的类型:Date、LocalDate、LocalDateTime、Instant、ZonedDateTime 等。

8. @JsonRootName(根节点名称)

@JsonRootName("response")
public class ApiResult<T> {
    private int code;
    private String msg;
    private T data;
}

序列化后

{
  "response": {
    "code": 200,
    "msg": "success",
    "data": {...}
  }
}

常用于统一响应结构。

9. Mix-in Annotations(不侵入实体类)

当你不能修改第三方类或想把注解放在 DTO 而不是实体时使用:

// Mix-in 类
public abstract class UserMixIn {
    @JsonIgnore
    public abstract String getPassword();
}

// 配置
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(User.class, UserMixIn.class);

效果:User 类本身不加任何注解,但序列化时 password 被忽略。

10. 自定义 Deserializer / Serializer(终极武器)

public class MoneyDeserializer extends JsonDeserializer<BigDecimal> {
    @Override
    public BigDecimal deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String text = p.getText();
        // 支持 "123.45", "¥123.45", "123,45" 等
        return new BigDecimal(text.replaceAll("[¥,]", ""));
    }
}

@JsonDeserialize(using = MoneyDeserializer.class)
private BigDecimal amount;

快速总结:你最应该立刻掌握的 5 个

  1. @JsonAnyGetter + @JsonAnySetter —— 处理动态字段
  2. @JsonUnwrapped —— 打平嵌套对象
  3. @JsonView —— 接口返回字段控制
  4. Mix-in Annotations —— 不侵入第三方类
  5. 自定义 Deserializer —— 处理非标准格式(金额、枚举、日期等)

这些特性一旦熟练使用,能让你的 JSON 处理代码更优雅、更安全、维护成本更低。

你项目里现在用 Jackson 遇到过哪些最痛苦的场景?可以告诉我,我帮你针对性给出最优解法。

文章已创建 4516

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部