Java Jackson如何将一个Pojo字段映射到2个(json)字段(相同的内容,不同的名称)
我使用Java Jackson如何将一个Pojo字段映射到2个(json)字段(相同的内容,不同的名称),java,csv,jackson,mixins,jackson-dataformat-csv,Java,Csv,Jackson,Mixins,Jackson Dataformat Csv,我使用Jackson将POJOs序列化为CSV。现在我们需要将某些字段的命名更改为snake_case。这可以通过@JsonNaming(PropertyNamingStrategy.snakecasetracety.class)轻松实现 出于兼容性原因,我们需要一些重命名的字段也使用它们的旧名称 例如: 默认值将序列化为“someField”,SnakeCaseStrategy将序列化为“someField” 如何使用这两种方法获得序列化?: { "someField"
Jackson
将POJO
s序列化为CSV
。现在我们需要将某些字段的命名更改为snake_case。这可以通过@JsonNaming(PropertyNamingStrategy.snakecasetracety.class)
轻松实现
出于兼容性原因,我们需要一些重命名的字段也使用它们的旧名称
例如:
默认值将序列化为“someField”,SnakeCaseStrategy
将序列化为“someField”
如何使用这两种方法获得序列化?:
{
"someField" : "one",
"some_field" : "one"
}
我的第一次尝试是混音:
public abstract class PojoFormat {
@JsonProperty("someField")
abstract String getSomeField();
}
但这实际上只会取消命名策略的更改。
因此,如何在序列化中复制字段—最好不要通过更改Pojo(当所有客户端都可以处理时,应该删除复制的字段)
小更新:
在我的真实类中,有一些使用的嵌套类,文档说明这不适用于自定义序列化程序(不知道这在这里有什么区别)。好吧,我以前从未见过,如果这个站点中有人知道如何使用,我将非常高兴 在我看来,最简单的方法是使用自定义序列化程序 例如:
import com.fasterxml.jackson.core.JsonGenerator;
导入com.fasterxml.jackson.databind.SerializerProvider;
导入com.fasterxml.jackson.databind.annotation.JsonSerialize;
导入com.fasterxml.jackson.databind.ser.std.std序列化程序;
@JsonSerializer(使用=PojoSerializer.class)
Pojo类{
私有字符串myValue;
//接球手和接球手
}
类PojoSerializer扩展了StdSerializer{
公共PojoSerializer(){
超级(Pojo.class);
}
@凌驾
public void serialize(Pojo值、JsonGenerator gen、SerializerProvider提供程序)引发IOException{
gen.writeStartObject();
gen.writeStringField(“myValue”,value.getMyValue());
gen.writeStringField(“我的值”,value.getMyValue());
writeEndObject将军();
}
}
模块
静态类Pojo{
私有字符串myValue;
公共字符串getMyValue(){
返回myValue;
}
公共Pojo setMyValue(字符串myValue){
this.myValue=myValue;
归还这个;
}
}
静态类PojoSerializer扩展了StdSerializer{
公共PojoSerializer(){
超级(Pojo.class);
}
@凌驾
public void serialize(Pojo值、JsonGenerator gen、SerializerProvider提供程序)引发IOException{
gen.writeStartObject();
gen.writeStringField(“myValue”,value.getMyValue());
gen.writeStringField(“我的值”,value.getMyValue());
writeEndObject将军();
}
}
公共静态void main(字符串[]args)引发JsonProcessingException{
最终ObjectMapper映射器=新ObjectMapper();
最终SimpleModule=新SimpleModule(“PojoModule”);
addSerializer(Pojo.class,新的PojoSerializer());
映射器注册表模块(模块);
最终Pojo Pojo=新Pojo();
setMyValue(“这是我的pojo的值”);
System.out.println(mapper.writeValueAsString(pojo));
}
反射
我为你写了一些代码,你可能想看看,以获得新的想法。
这是一种通用方法(只是为了不编写多个序列化程序)
//序列化程序将在ObjectMapper模块中注册。
静态类Pojo{
私有字符串myValue=“With snake and camel”;
private String value=“不带蛇格”;
私有字符串thirdValue=“snake&camel”;
}
//使用注释
@JsonSerialize(使用=PojoSerializer.class)
静态类Pojo2{
私有字符串pojoName=“Pojo 2”;
私有字符串pojo=“pojp”;
}
静态类PojoSerializer扩展了StdSerializer{
公共PojoSerializer(){
super(Object.class);
}
@凌驾
public void serialize(对象值、JsonGenerator gen、SerializerProvider提供程序)引发IOException{
gen.writeStartObject();
最终字段[]字段=value.getClass().getDeclaredFields();
用于(最终字段:字段){
最终字符串名称=field.getName();
最终字符串字段值;
试一试{
//不要用这个!
fieldValue=(字符串)field.get(值);
}捕获(非法访问例外e){
抛出新的运行时异常(e);
}
字节firstUpperCase=-1;
对于(字节索引=0;索引A'&字符
您可以尝试使用注释并为每个POJO
额外映射定义向后兼容性
让我们创建一个简单的界面:
interface CompatibleToVer1 {
@JsonAnyGetter
Map<String, Object> getCompatibilityView();
}
CsvSchema createSchemaFor(CompatibleToVer1 entity) {
CsvSchema.Builder builder = CsvSchema.builder();
entity.getCompatibilityView().keySet().forEach(builder::addColumn);
return builder.build();
}
以上代码打印:
{
"root_id" : 1,
"some_field" : 123,
"some_name" : "Tom",
"someField" : 123,
"rootId" : 1
}
some_field,some_name,root_id,rootId,someField
123,Tom,1,1,123
124,Jerry,2,2,124
但是对于CSV
我们需要创建额外的配置:
CsvMapper csvMapper = CsvMapper.builder().build();
CsvSchema pojoExtraScheme = CsvSchema.builder()
.addColumn("someField")
.build();
CsvSchema rootExtraScheme = CsvSchema.builder()
.addColumn("rootId")
.build();
CsvSchema compatibleSchema = CsvSchema.emptySchema()
.withHeader()
.withColumnsFrom(csvMapper.schemaFor(RootPojo.class))
.withColumnsFrom(rootExtraScheme)
.withColumnsFrom(csvMapper.schemaFor(SomePojo.class))
.withColumnsFrom(pojoExtraScheme);
SomePojo tom = new SomePojo(123, "Tom");
SomePojo jerry = new SomePojo(124, "Jerry");
List<RootPojo> pojos = Arrays.asList(new RootPojo(1, tom), new RootPojo(2, jerry));
ObjectWriter writer = csvMapper.writer(compatibleSchema);
System.out.println(writer.writeValueAsString(pojos));
如果您不想两次指定额外的列,可以基于我们的界面实现生成器方法:
interface CompatibleToVer1 {
@JsonAnyGetter
Map<String, Object> getCompatibilityView();
}
CsvSchema createSchemaFor(CompatibleToVer1 entity) {
CsvSchema.Builder builder = CsvSchema.builder();
entity.getCompatibilityView().keySet().forEach(builder::addColumn);
return builder.build();
}
使用方法如下:
CsvSchema compatibleSchema = CsvSchema.emptySchema()
.withHeader()
.withColumnsFrom(csvMapper.schemaFor(RootPojo.class))
.withColumnsFrom(createSchemaFor(new RootPojo()))
.withColumnsFrom(csvMapper.schemaFor(SomePojo.class))
.withColumnsFrom(createSchemaFor(new SomePojo()));
使用JsonAn
CsvMapper csvMapper = CsvMapper.builder().build();
CsvSchema pojoExtraScheme = CsvSchema.builder()
.addColumn("someField")
.build();
CsvSchema rootExtraScheme = CsvSchema.builder()
.addColumn("rootId")
.build();
CsvSchema compatibleSchema = CsvSchema.emptySchema()
.withHeader()
.withColumnsFrom(csvMapper.schemaFor(RootPojo.class))
.withColumnsFrom(rootExtraScheme)
.withColumnsFrom(csvMapper.schemaFor(SomePojo.class))
.withColumnsFrom(pojoExtraScheme);
SomePojo tom = new SomePojo(123, "Tom");
SomePojo jerry = new SomePojo(124, "Jerry");
List<RootPojo> pojos = Arrays.asList(new RootPojo(1, tom), new RootPojo(2, jerry));
ObjectWriter writer = csvMapper.writer(compatibleSchema);
System.out.println(writer.writeValueAsString(pojos));
some_field,some_name,root_id,rootId,someField
123,Tom,1,1,123
124,Jerry,2,2,124
CsvSchema createSchemaFor(CompatibleToVer1 entity) {
CsvSchema.Builder builder = CsvSchema.builder();
entity.getCompatibilityView().keySet().forEach(builder::addColumn);
return builder.build();
}
CsvSchema compatibleSchema = CsvSchema.emptySchema()
.withHeader()
.withColumnsFrom(csvMapper.schemaFor(RootPojo.class))
.withColumnsFrom(createSchemaFor(new RootPojo()))
.withColumnsFrom(csvMapper.schemaFor(SomePojo.class))
.withColumnsFrom(createSchemaFor(new SomePojo()));