You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Jackson同时反序列化驼峰式与下划线式命名的JSON?

解决Jackson兼容驼峰/下划线JSON反序列化+序列化仅输出下划线的问题

要实现一个ObjectMapper同时支持两种命名格式的反序列化,且序列化固定输出下划线格式,有两种可行方案,以下是具体实现:

方案一:全局自定义命名策略(适合多字段场景)

通过自定义PropertyNamingStrategy,让序列化时使用下划线规则,反序列化时自动兼容驼峰和下划线格式:

1. 自定义命名策略类

import com.fasterxml.jackson.databind.MapperConfig;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;

public class MixedNamingStrategy extends PropertyNamingStrategy {
    // 驼峰命名策略(用于转换下划线到驼峰)
    private final PropertyNamingStrategy camelCase = PropertyNamingStrategies.LOWER_CAMEL_CASE;
    // 下划线命名策略(用于序列化输出)
    private final PropertyNamingStrategy snakeCase = PropertyNamingStrategies.SNAKE_CASE;

    // 序列化字段时使用下划线策略
    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return snakeCase.nameForField(config, field, defaultName);
    }

    // 序列化getter方法对应字段时使用下划线策略
    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return snakeCase.nameForGetterMethod(config, method, defaultName);
    }

    // 序列化setter方法对应字段时使用下划线策略
    @Override
    public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
        return snakeCase.nameForSetterMethod(config, method, defaultName);
    }

    // 反序列化时统一转换字段名为驼峰格式,兼容两种输入
    @Override
    public String translate(String input) {
        // 先把输入转为下划线格式,再转回驼峰——无论输入是驼峰还是下划线,最终都得到实体类的驼峰字段名
        String snakeForm = snakeCase.translate(input);
        return camelCase.translate(snakeForm);
    }
}

2. 配置ObjectMapper并测试

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.JsonProcessingException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

public class Test {
    public static void main(final String[] args) throws JsonProcessingException {
        final ObjectMapper objectMapper = new ObjectMapper();
        // 应用自定义命名策略
        objectMapper.setPropertyNamingStrategy(new MixedNamingStrategy());
        // 忽略未知字段,避免非目标字段导致报错
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

        // 测试驼峰JSON反序列化
        Parent camelCaseResult = objectMapper.readValue("{\"testField\":\"test\"}", Parent.class);
        System.out.println("驼峰JSON反序列化结果:" + camelCaseResult);

        // 测试下划线JSON反序列化
        Parent snakeCaseResult = objectMapper.readValue("{\"test_field\":\"test\"}", Parent.class);
        System.out.println("下划线JSON反序列化结果:" + snakeCaseResult);

        // 测试序列化(输出下划线格式)
        String serializedJson = objectMapper.writeValueAsString(camelCaseResult);
        System.out.println("序列化输出(下划线格式):" + serializedJson);
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    static class Parent {
        String testField;
    }
}

方案二:字段级别名配置(适合少字段场景)

如果实体类字段不多,直接给字段添加@JsonAlias注解指定别名,同时设置序列化策略为下划线格式:

1. 修改实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
static class Parent {
    // 允许反序列化时识别test_field别名
    @JsonAlias("test_field")
    String testField;
}

2. 配置ObjectMapper并测试

public static void main(final String[] args) throws JsonProcessingException {
    final ObjectMapper objectMapper = new ObjectMapper();
    // 序列化时使用下划线命名策略
    objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
    objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

    // 测试两种格式反序列化
    System.out.println(objectMapper.readValue("{\"testField\":\"test\"}", Parent.class));
    System.out.println(objectMapper.readValue("{\"test_field\":\"test\"}", Parent.class));

    // 测试序列化输出下划线格式
    System.out.println(objectMapper.writeValueAsString(new Parent("test")));
}

两种方案对比

  • 自定义命名策略:全局生效,无需逐个字段配置,适合字段数量多的场景,维护成本低。
  • @JsonAlias注解:简单直观,适合字段少的场景,可针对特定字段灵活配置别名。

内容的提问来源于stack exchange,提问作者Suzuki Yuu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:45:03