我想创建一个配置文件,该文件允许我定义不同的数据生成器,每个数据生成器都需要不同的配置。但是,它们都共享相同的方法,generateRow因此这些类都可以实现一个接口。我正在使用 Jackson 版本 2.9.4。
为了说明这一点,这里有两个示例配置文件:
{
"data": {
"type": "standard",
"config": {
"rows": 1000,
"columns": 10
}
}
}
Run Code Online (Sandbox Code Playgroud)
和
{
"data": {
"type": "totalSize",
"config": {
"sizeInBytes": 1073741824,
"cellDensityInBytes": 12,
"columns": 5
}
}
}
Run Code Online (Sandbox Code Playgroud)
第一个数据生成器只是创建一个具有给定行数和列数的文件,第二个生成器创建一个预定义大小的文件,确定满足配置变量(即列数和单元密度)所需的行数)。
所以,我创建了一个界面:
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeInfo.As;
import com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = IGenerateRows.PROPERTY, defaultImpl = StandardRowGenerator.class)
@JsonSubTypes(value = { @Type(StandardRowGenerator.class) })
public interface IGenerateRows {
public static final String PROPERTY = "type";
public String[] generateRow();
}
Run Code Online (Sandbox Code Playgroud)
我至少有一个具体的实现:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonTypeName(value = StandardRowGenerator.TYPE)
public class StandardRowGenerator {
public static final String TYPE = "standard";
private static final String ROWS = "rows";
private static final String COLUMNS = "columns";
@JsonProperty(value = ROWS, required = true)
private int rows;
@JsonProperty(value = COLUMNS, required = true)
private int columns;
}
Run Code Online (Sandbox Code Playgroud)
我不明白的是如何处理config我的配置文件中的数据生成器节点的节点。我如何正确设置我的具体类来定义生成数据所需的属性?
在我的引导代码中,我实例化了整个配置对象,如下所示:
new ObjectMapper().readValue(inputStream, DataGeneratorConfig.class);
Run Code Online (Sandbox Code Playgroud)
为了简洁起见,我省略了 getter 和 setter,以及与当前问题无关的配置文件的其余部分。如果我可以提供任何其他详细信息或代码,请告诉我。
我有点不确定你的类的底层实现以及它们生成的数据等。
但你的思路是正确的,我已经将你所寻找的工作示例推送到了这个存储库,请注意,这是使用https://projectlombok.org/生成 POJO,因为我很懒。
https://github.com/Flaw101/jackson-type-info
Data类中来处理它。测试中的 ObjectMapper 启用了所需的功能。看起来IGenerateRow像,
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = RowGenerator.PROPERTY, defaultImpl = StandardRowGenerator.class)
@JsonSubTypes(value = { @Type(StandardRowGenerator.class), @Type(TotalSizeGeneartor.class) })
@JsonRootName(value = "data")
public abstract interface RowGenerator {
public static final String PROPERTY = "type";
Config getConfig();
}
Run Code Online (Sandbox Code Playgroud)
Config 只是具体实现的标记接口。
public interface Config {
}
Run Code Online (Sandbox Code Playgroud)
SimpleTypeGenerator 现在变成了,
@JsonTypeName(value = StandardRowGenerator.TYPE)
@Data
public class StandardRowGenerator implements RowGenerator {
public static final String TYPE = "standard";
private StandardConfig config;
@Data
public static class StandardConfig implements Config {
private int rows;
private int columns;
}
}
Run Code Online (Sandbox Code Playgroud)
类似地TotalSize,
@JsonTypeName(value = TotalSizeGeneartor.TYPE)
@Data
public class TotalSizeGeneartor implements RowGenerator {
public static final String TYPE = "totalSize";
private TotalSizeConfig config;
@Data
public static class TotalSizeConfig implements Config {
private long sizeInBytes;
private int cellDensityInBytes;
private int columns;
}
}
Run Code Online (Sandbox Code Playgroud)
这些可以通过更多/更好的通用类型信息来改进,以便能够获得对配置的具体引用。
测试类读取资源文件夹中的两个配置,将它们写入对象并返回到字符串,比较之前/之后,不存在 null 或空属性,并且接口具有正确的实现。
注意,这使用了assertThatfromAssertJ
public class JacksonTest {
private ObjectMapper mapper;
private String json;
@Before
public void setup() throws Exception {
mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
}
@Test
public void testDeserStandard() throws Exception {
json = StringUtils.deleteWhitespace(
new String(Files.readAllBytes(Paths.get("src/main/resources/standard.json")), StandardCharsets.UTF_8));
RowGenerator generator = mapper.readValue(json, RowGenerator.class);
assertThat(generator).hasNoNullFieldsOrProperties().isExactlyInstanceOf(StandardRowGenerator.class);
assertThat(generator.getConfig()).hasNoNullFieldsOrProperties().isExactlyInstanceOf(StandardConfig.class);
assertThat(json).isEqualTo(mapper.writeValueAsString(generator));
System.out.println(generator);
}
@Test
public void testDeserTotalsize() throws Exception {
json = StringUtils.deleteWhitespace(
new String(Files.readAllBytes(Paths.get("src/main/resources/totalsize.json")), StandardCharsets.UTF_8));
RowGenerator generator = mapper.readValue(json, RowGenerator.class);
assertThat(generator).hasNoNullFieldsOrProperties().isExactlyInstanceOf(TotalSizeGeneartor.class);
assertThat(generator.getConfig()).hasNoNullFieldsOrProperties().isExactlyInstanceOf(TotalSizeConfig.class);
assertThat(json).isEqualTo(mapper.writeValueAsString(generator));
System.out.println(generator);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5643 次 |
| 最近记录: |