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

Spring Boot中如何根据环境配置不同的@JsonProperty属性值

解决方案

核心思路是利用Jackson的扩展能力实现动态字段名映射,结合多环境配置即可,不需要维护多套请求类,以下是3种常用的实现方案:


方案1:自定义环境感知的JsonProperty注解

通过自定义注解承载不同环境的字段ID,配合自定义序列化器动态输出对应Key。

步骤1:定义自定义注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnvJsonProperty {
    // 测试环境的字段ID
    String test();
    // 生产环境的字段ID
    String prod();
}

步骤2:改造请求类

替换原有的@JsonProperty为自定义注解:

public class RequestClass {
  @EnvJsonProperty(test = "123-test", prod = "123")
  private String name;

  @EnvJsonProperty(test = "124-test", prod = "124")
  private String email;

  @EnvJsonProperty(test = "129-test", prod = "129")
  private String mobile;
}

步骤3:实现自定义序列化器

根据当前激活的环境,动态读取对应注解值作为序列化Key:

public class EnvRequestSerializer extends StdSerializer<RequestClass> {
    // 从配置文件/配置中心读取当前激活环境,Spring项目可直接通过@Value注入
    private final String activeEnv;

    public EnvRequestSerializer(String activeEnv) {
        super(RequestClass.class);
        this.activeEnv = activeEnv;
    }

    @Override
    public void serialize(RequestClass request, JsonGenerator gen, SerializerProvider provider) throws IOException, IllegalAccessException {
        gen.writeStartObject();
        Field[] fields = RequestClass.class.getDeclaredFields();
        for (Field field : fields) {
            EnvJsonProperty anno = field.getAnnotation(EnvJsonProperty.class);
            if (anno == null) continue;
            field.setAccessible(true);
            String key = "prod".equals(activeEnv) ? anno.prod() : anno.test();
            gen.writeObjectField(key, field.get(request));
        }
        gen.writeEndObject();
    }
}

步骤4:绑定序列化器

给请求类添加序列化注解即可生效:

@JsonSerialize(using = EnvRequestSerializer.class)
public class RequestClass {
    // 字段定义不变
}

方案2:自定义Jackson字段命名策略

如果不想修改原有请求类的注解,可通过自定义PropertyNamingStrategy实现映射,映射关系完全放在配置文件中,改动量更小。

步骤1:配置多环境映射关系

将不同环境的字段映射放到对应环境的配置文件中,示例(YAML格式):

# 测试环境配置
field:
  mapping:
    name: "123-test"
    email: "124-test"
    mobile: "129-test"
# 生产环境配置
field:
  mapping:
    name: "123"
    email: "124"
    mobile: "129"

步骤2:实现自定义命名策略

public class EnvFieldNamingStrategy extends PropertyNamingStrategy {
    private final Map<String, String> fieldMapping;

    public EnvFieldNamingStrategy(Map<String, String> fieldMapping) {
        this.fieldMapping = fieldMapping;
    }

    @Override
    public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
        return fieldMapping.getOrDefault(defaultName, defaultName);
    }
}

步骤3:绑定命名策略

将自定义命名策略设置到你用于序列化请求的ObjectMapper实例中即可:

// 从配置中读取当前环境的映射关系
Map<String, String> mapping = getEnvFieldMapping();
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(new EnvFieldNamingStrategy(mapping));

方案3:请求拦截器动态替换Key

如果是老项目改造,不想修改序列化逻辑,可在请求发送前的拦截器中修改序列化后的参数Key:

  1. 先按原有逻辑序列化请求得到JSON字符串
  2. 读取当前环境的字段映射关系,遍历替换JSON的Key为对应环境的ID
  3. 将替换后的JSON作为请求体发送

方案选型建议

  • 字段数量少、映射关系稳定:选方案1,逻辑直观,耦合度低
  • 字段多、映射关系调整频繁:选方案2,修改配置即可生效,不需要动业务代码
  • 老项目改造成本高:选方案3,完全不侵入原有请求类和序列化逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:06:03