使用Jackson将布尔值映射为枚举值
我需要把一个YAML的布尔字段反序列化为一个枚举类型,反向也需要。两者的名称也不同。
重要的是,在YAML中针对Java字段应该只有一个键("darkTheme")。
该枚举不得声明布尔字段。
为了向后兼容,YAML字段必须保持布尔类型。
最小可复现示例(MRE):
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); // fails
}
}
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;
}
}
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 dark(boolean isDark) {
return isDark ? DARK : BASE;
}
@JsonValue
public static boolean isDark(AppStyle style) {
return style == DARK;
}
}
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.15.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.15.1</version>
</dependency>
Java 8。
解决方案
基于 @JsonValue 的Javadoc:
标记注解,表示被注解的访问器(字段或“getter”方法[一个返回类型非void、无参数的方法])的值将被用作该实例的单一序列化值,而不是通常的从值中收集属性的方式。通常该值是一个简单的标量类型(String或 Number),但它也可以是任何可序列化类型(集合、Map或 Bean)。
我相信你的 isDark 方法需要是一个无参数的实例方法。
@JsonValue
public boolean isDark() {
return this == DARK;
}
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。