FasterXML / FasterXML/jackson-dataformats-binary

Support @JsonSubTypes in schema generation and serialization

未關閉
#11 6 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
avro
主要語言
Java
星號
347
分支
156
平均合併
3 天 3 小時
30 天內合併 PR
22

描述

(moved from https://github.com/FasterXML/jackson-dataformat-avro/issues/28 authored by @osi)

I'd like to get the JsonSubTypes annotation working for schema generation and serialization.

For schema generation, I think it should be a union of all the possible sub-types.

For serialization, if the configuration is such that the type name would be included as a property, ignore that, since it will be included as the name of the record type.

I have written some failing tests, but it is unclear to me how to proceed, since the TypeIdResolver doesn't provided a way to interrogate all possible types.

``` java
package com.fasterxml.jackson.dataformat.avro;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.apache.avro.Schema;
import org.junit.Test;

import java.util.Arrays;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class JsonTypeInfoTest {

@Test
public void testGenerateSchemaForSubTypes() throws Exception {
AvroMapper mapper = new AvroMapper();
AvroSchema schema = mapper.schemaFor(Thing.class);

Schema stringOrNull = Schema.createUnion(Arrays.asList(Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.STRING)));
Schema thingOne = Schema.createRecord(
ThingOne.class.getSimpleName(),
"Schema for " + ThingOne.class.getName(),
ThingOne.class.getPackage().getName(),
false);
thingOne.setFields(Arrays.asList(
new Schema.Field("favoriteColor", stringOrNull, null, null),
new Schema.Field("name", stringOrNull, null, null)
));

Schema thingTwo = Schema.createRecord(
ThingTwo.class.getSimpleName(),
"Schema for " + ThingTwo.class.getName(),
ThingTwo.class.getPackage().getName(),
false);
thingTwo.setFields(Arrays.asList(
new Schema.Field("favoriteFood", stringOrNull, null, null),
new Schema.Field("name", stringOrNull, null, null)
));

Schema expected = Schema.createUnion(Arrays.asList(thingOne, thingTwo));
assertEquals(expected, schema.getAvroSchema());
}

@Test
public void testSerializeSubType() throws Exception {
AvroMapper mapper = new AvroMapper();
AvroSchema schema = mapper.schemaFor(Thing.class);

assertNotNull(mapper.writer(schema).writeValueAsBytes(new ThingOne("hello", "blue")));
}

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "@type")
@JsonSubTypes({
@JsonSubTypes.Type(value = ThingOne.class, name = "one"),
@JsonSubTypes.Type(value = ThingTwo.class, name = "two")
})
public interface Thing {
@JsonProperty
String name();
}

public static class ThingOne implements Thing {
public final String favoriteColor;
private final String name;

public ThingOne(String name, String favoriteColor) {
this.name = name;
this.favoriteColor = favoriteColor;
}

@Override
public String name() {
return name;
}
}

public static class ThingTwo implements Thing {
public final String favoriteFood;
private final String name;

public ThingTwo(String name, String favoriteFood) {
this.name = name;
this.favoriteFood = favoriteFood;
}

@Override
public String name() {
return name;
}
}
}
```

貢獻指南

這個儲存庫沒有索引到貢獻指南

評估

這個 Issue 還沒有評估資料。

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。