反序列化期间JsonProperty的动态绑定

时间:2018-02-15 12:32:59

标签: java json serialization reflection jackson

我想知道是否有任何合法的方法来动态分配JsonProperty的名称,所以我会在需要时随时更改它?话虽如此,我的意思是:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Record
{
    public String Name;

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static class QueryResult<T>
    {
       public List<T> records;
    }

    public static class QueryResultRecord extends QueryResult<Record>
    {
    }
}

如上所述,我有一个属性Name,默认情况下将命名为&#34; Name&#34;像这样:

[
  {
    Name: "Test",
  },
  {
     Name: "test",
  },
]

即使我可以灵活地使用 @JsonProperty(&#34;名称&#34;),但这不是解决方案。我需要的是在需要时多次更改它,因为我有一些依赖它的参数化查询。所以我想要 Name,FirstName,LastName 等等。 refletion api在这里使用它是正确的吗?

2 个答案:

答案 0 :(得分:1)

最简单的合法方式是编写自定义AnnotationIntrospector

import com.fasterxml.jackson.databind.PropertyName;
import com.fasterxml.jackson.databind.introspect.Annotated;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;

public class MyJacksonAnnotationIntrospector extends JacksonAnnotationIntrospector
{
    private static final long serialVersionUID = 1L;

    @Override
    public PropertyName findNameForSerialization(Annotated a) {
        PropertyName pn = super.findNameForSerialization(a);
        if (pn.getSimpleName().equals("Name")) {
            return pn.withSimpleName("LastName");  // set property name to your heart's content...
        }
        return pn;
    }
}

然后将其传递给jackson mapper:

ObjectMapper mapper = new ObjectMapper();
mapper.setAnnotationIntrospector(new MyJacksonAnnotationIntrospector());
Record r1 = new Record();
mapper.writeValue(System.out, r1);

注意:反序列化期间使用相同的introspector。

答案 1 :(得分:0)

我没有找到任何简单的方法,但您可以使用自定义JsonSerializer并在其中实现您的逻辑:

// Record class
@JsonIgnoreProperties(ignoreUnknown = true)
public class Record {

    protected String name;

    public Record(String name) {
        this.name = Name;
    }
    // ...
}
// RecordJsonSerializer class
public static class RecordJsonSerializer extends JsonSerializer<Record> {

    private static final String[] NAMES = new String[]{
        "Name",
        "FirstName"
        // ...
    };

    protected int idx;

    public RecordJsonSerializer() {
        idx = 0;
    }

    @Override
    public void serialize(Record r, JsonGenerator jg, SerializerProvider sp) throws IOException, JsonProcessingException {
        jg.writeStartObject();
        jg.writeObjectField(NAMES[idx++], r.name); // Change the field name
        jg.writeEndObject();
    }
}
// Use case
Record[] records = new Record[]{
    new Record("r0"),
    new Record("r1")
};

ObjectMapper mapper = new ObjectMapper()
    .registerModule(
        new SimpleModule("Record")
        .addSerializer(Record.class, new RecordJsonSerializer())); // Register the serializer instance

System.out.println(mapper.writeValueAsString(records));

输出结果为:[{"Name":"r0"},{"FirstName":"r1"}]

当然,您必须更改逻辑以定义在序列化对象时使用的属性名称(我将使用3条记录崩溃,但它只是一个简单的示例)。