Java Object extending a list to Json with Jackson

2019-05-29 07:25发布

问题:

I want to convert a object that is extending a list to Json using Jackson. Example:

public class TryToSerialize extends ArrayList<String>
{
    private int number;
    private String word;

    public TryToSerialize(){
        number = 0;
        word = "";
    }

    @JsonProperty
    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }
    @JsonProperty
    public String getWord() {
        return word;
    }

    public void setWord(String word) {
        this.word = word;
    }

    @JsonIgnore
    public String getAsJSON() throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(new File("c:\\tts.json"), this);
        return mapper.writeValueAsString(this) ; 
    }
}

When I do serialize this I will only get the Array portion.

    TryToSerialize tts = new TryToSerialize();
    tts.setNumber(10);
    tts.setWord("Working");
    tts.add("first");
    tts.add("second");
    tts.add("third");
    String json = tts.getAsJSON();

Json:

["first","second","third"]

I am looking for a way to include the other variables of the object.

回答1:

As your object extends one of the classes for which a default serialization behavior exists, your extra fields are just ignored.

Now, one thing which is unclear to me is what should be the expected result.

If you are expecting a result such as:

{"number":10,"word":"Working","values":["first","second","third"]}

Then you should be able to do it thanks to a custom serializer such as the following:

public class MySerializer extends JsonSerializer<TryToSerialize> {
    @Override
    public void serialize(TryToSerialize toSerialize, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        jgen.writeStartObject();
        jgen.writeNumberField("number", toSerialize.getNumber());
        jgen.writeStringField("word", toSerialize.getWord());
        provider.defaultSerializeField("values", toSerialize.iterator(), jgen);
        jgen.writeEndObject();
    }
}

If you are expecting a result such as:

[10,"Working","first","second","third"]

Then, serializer will look like the following:

public class MySerializer extends JsonSerializer<TryToSerialize> {
    @Override
    public void serialize(TryToSerialize toSerialize, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {
        jgen.writeStartArray();
        jgen.writeNumber(toSerialize.getNumber());
        jgen.writeString(toSerialize.getWord());
        for (Iterator<String> iterator = toSerialize.iterator(); iterator.hasNext();) {
            jgen.writeString((String) iterator.next());         
        }
        jgen.writeEndArray();
    }
}

Then, in both cases annotate your class with:

@JsonSerialize(using = MySerializer.class)

There may be a smarter ways but this should work...