java – 如何使用@JsonTypeInfo和@JsonSubTypes来实例化具有不同配置的类?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 如何使用@JsonTypeInfo和@JsonSubTypes来实例化具有不同配置的类?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5229字,纯文字阅读大概需要8分钟。
内容图文
![java – 如何使用@JsonTypeInfo和@JsonSubTypes来实例化具有不同配置的类?](/upload/InfoBanner/zyjiaocheng/782/ca9f19d2e8c547fea22ce44945483e42.jpg)
我想创建一个配置文件,允许我定义不同的数据生成器,每个数据生成器都需要不同的配置.但是,它们都共享相同的方法generateRow,因此这些类都可以实现一个接口.我正在使用杰克逊版本2.9.4.
为了说明,这里有两个示例配置文件:
{
"data": {
"type": "standard",
"config": {
"rows": 1000,
"columns": 10
}
}
}
和
{
"data": {
"type": "totalSize",
"config": {
"sizeInBytes": 1073741824,
"cellDensityInBytes": 12,
"columns": 5
}
}
}
第一个数据生成器只是创建一个具有给定行数和列数的文件,第二个生成器创建一个预定义大小的文件,确定满足配置变量所需的行数(即列数和单元密度) ).
所以,我创建了一个界面:
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();
}
我至少有一个具体的实现:
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;
}
我无法弄清楚的是,如何处理配置文件中数据生成器节点的配置节点.我如何正确设置我的具体类来定义生成数据所需的属性?
在我的引导代码中,我实例化整个配置对象,如下所示:
new ObjectMapper().readValue(inputStream, DataGeneratorConfig.class);
为简洁起见,我省略了getter和setter,以及配置文件的其余部分,这与手头的问题无关.如果我可以提供任何其他详细信息或代码,请告诉我们.
解决方法:
我对你的类的底层实现以及它们生成的数据等有点不确定.
但是你是按照正确的方式排列的,我已经推动了我认为这个回购的实际例子,注意这是使用https://projectlombok.org/来生成POJO,因为我很懒.
https://github.com/Flaw101/jackson-type-info
>它将忽略“数据”节点.这主要是因为我很懒,实体可以包装在Data类中来处理它.测试中的ObjectMapper启用了此功能所需的功能.
>它将读/写配置类的数据.与您指定的示例内联.
>自动取消数据化是没有快速的胜利.你也许可以把它写到地图上 – >对象,但这是非常混乱和使用像lombok / IDE类geneartion这样的工具制作这些实体应该是几秒钟的工作.
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();
}
而Config只是混凝土冲击的标记界面.
public interface Config {
}
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;
}
}
和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;
}
}
这些可以通过更多/更好的泛型类型信息来改进,以便能够获得对配置的具体引用.
测试类在资源文件夹中读取您的两个配置,将它们写入对象并返回到比较之前/之后的字符串,没有null或空属性,并且接口具有正确的实现.
注意,这使用来自AssertJ的assertThat
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);
}
}
内容总结
以上是互联网集市为您收集整理的java – 如何使用@JsonTypeInfo和@JsonSubTypes来实例化具有不同配置的类?全部内容,希望文章能够帮你解决java – 如何使用@JsonTypeInfo和@JsonSubTypes来实例化具有不同配置的类?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。