使用Jackson实现YAML布尔字段与Java枚举的双向映射(兼容需求)
使用Jackson实现YAML布尔字段与Java枚举的双向映射(兼容需求)
嘿,这个问题我熟~你的测试里序列化步骤失败,核心问题出在枚举类的@JsonValue注解用法不对,Jackson要求@JsonValue必须标记在实例方法上,而不是静态方法。咱们一步步调整就能满足所有约束要求:
核心问题分析
原来的AppStyle枚举中,@JsonValue标记了静态方法,Jackson无法识别这个静态方法来完成枚举到布尔值的序列化。而@JsonCreator的反序列化逻辑是正确的,只需要调整序列化的逻辑。
修改后的枚举类(关键修复)
把@JsonValue移到实例方法上,让每个枚举实例自己决定要序列化的布尔值:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; public enum AppStyle { BASE, DARK; @JsonCreator(mode = JsonCreator.Mode.DELEGATING) public static AppStyle fromBoolean(boolean isDark) { // 反序列化:把YAML的boolean转成枚举 return isDark ? DARK : BASE; } @JsonValue public boolean toBoolean() { // 序列化:把枚举实例转成对应的boolean值 return this == DARK; } }
其他代码保持不变
你的AppSettings类和测试类不需要修改,直接沿用原来的代码即可:
// AppSettings.java 保持原样 import com.fasterxml.jackson.annotation.JsonProperty; public class AppSettings { @JsonProperty("darkTheme") private AppStyle style; public void setStyle(AppStyle style) { this.style = style; } public AppStyle getStyle() { return style; } }
// YamlTest.java 保持原样 import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; public class YamlTest { @Test void testSomething() throws JsonProcessingException { String yaml = "darkTheme: true"; YAMLFactory factory = new YAMLFactory(); ObjectMapper mapper = new ObjectMapper(factory); AppSettings settings = mapper.readValue(yaml, AppSettings.class); assertEquals(AppStyle.DARK, settings.getStyle()); String serializedSettings = mapper.writeValueAsString(settings); String expectedYaml = "---\n" + "darkTheme: true\n"; assertEquals(expectedYaml, serializedSettings); // 现在会通过 } }
验证效果
现在重新运行测试:
- 反序列化:YAML的
darkTheme: true会被正确转换成AppStyle.DARK,第一个断言通过; - 序列化:
AppSettings对象会被序列化为---\ndarkTheme: true\n,和预期完全一致,第二个断言也会通过。
所有约束要求的满足情况
- ✅ YAML中仅存在
darkTheme一个键:通过@JsonProperty("darkTheme")绑定到style字段,符合要求; - ✅ 枚举未声明布尔字段:枚举仅包含两个实例,没有额外字段,符合要求;
- ✅ YAML字段保持boolean类型:序列化后仍然输出
true/false,完全兼容旧版本配置。
备注:内容来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

