4
votes

I am using Jackson in order to send data in JSON type between a client a server. I am trying to use Jackson's full binding feature and I am applying it over a standard POJO. The problem is that Jackson seem to add redundant data during marshaling on the server so when I try to unmarshall it back to the POJO on the client side I'm getting an error.

Here's an excerpt of the Jackson String:

{"_class":"com.mycoomp.MyObject","_id":{"time":1300314145000,"new":false,"machine":1652794940,"inc":-510750341},"language":"","type".....

MyObject contains "language" and "type" but it it doesn't contain “time”, “new” and “machine” that are not part of it but on the client side i'm getting this error:

Unrecognized field "time" (Class org.bson.types.ObjectId), not marked as ignorable at [Source: java.io.StringReader@1c56c60; line: 1, column: 102] (through reference chain: com.mycomp.MyObject["_id"]->org.bson.types.ObjectId["time"])

Any ideas...?

3
Please add full definition of POJO (MyObject?) - StaxMan

3 Answers

2
votes

The solution is to provide a custom serializer/deserializer for ObjectId:

public class ObjectIdMapping {
    public static class ObjectIdSerializer extends JsonSerializer<ObjectId>{
        @Override
        public void serialize(ObjectId  id, JsonGenerator json,
                SerializerProvider provider) throws IOException,
                JsonProcessingException {
            json.writeString(id.toString());

        }
    }
    public static class ObjectIdDeerializer extends JsonDeserializer<ObjectId>{
        @Override
        public ObjectId deserialize(JsonParser jp, DeserializationContext context)
                throws IOException, JsonProcessingException {
            if (!ObjectId.isValid(jp.getText())) throw context.mappingException("invalid ObjectId " + jp.getText());
            return new ObjectId(jp.getText());
        }
    }
}   

And register them as any of the methods described in the documentation. For example, add in your POJO:

@JsonSerialize(using = ObjectIdMapping.ObjectIdSerializer.class)
@JsonDeserialize(using = ObjectIdMapping.ObjectIdDeerializer.class)
public ObjectId od;
1
votes

You need to give type definitions for types you are serializing. Jackson does not add any entries that are not discoverable from objects (via getters, public fields, or explicitly annotated); except in cases where you add @JsonTypeInfo annotation to also add type identifier.

So maybe object you are serializing has more public fields that will be serialized?

1
votes

I've just come across this as I had the same problem. Seems like a job for the mongo-jackson-mapper

I would also advise taking infrastructural classes such as ObjectId out of your domain.