How to serialize ObjectId to JSON?

2019-04-17 01:33发布

I want to serialize ObjectId of my Product class to JSON. I got the following JSON:

[{"name":"Play for Java: Covers Play 2","type":"Book","company":"Manning Publications","price":30.0,"imagePath":"public/images/play-for-java.png","rating":4.5,"category":"Computer","author":"Nicolas Leroux","publicationDate":1396224000000,"numPage":320,"_id":539da7a6370882f10d5c2777}]

You can notice that the "_id" didn't be properly serialized, it should be "539da7a6370882f10d5c2777" (with double quotes) and not just 539da7a6370882f10d5c2777.

Therefore, I have tried to implement my own ObjectIdSerializer as following:

import java.io.IOException;

import org.bson.types.ObjectId;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

public class ObjectIdSerializer extends JsonSerializer<ObjectId> {
    @Override
    public void serialize(ObjectId value, JsonGenerator jsonGen,SerializerProvider provider) throws IOException,
            JsonProcessingException {
        jsonGen.writeString(value.toString());
    }
}

It gave me the different error: java.lang.String cannot be cast to org.bson.types.ObjectId (through reference chain: models.Book["_id"])

Here are my Product class and Book class:

Product.java

@JsonTypeInfo(use= JsonTypeInfo.Id.CLASS,property="_class")
public class Product {
    @ObjectId @Id
    @JsonSerialize(using = ObjectIdSerializer.class)
    protected String id;
    @JsonProperty("name")
    protected String name;
    @JsonProperty("type")
    protected String type;
    @JsonProperty("description")
    protected String description;
    @JsonProperty("company")
    protected String company;
    @JsonProperty("price")
    protected float price;
    @JsonProperty("imagePath")
    protected String imagePath;
    @JsonProperty("imageName")
    protected String imageName;
    @JsonProperty("rating")
    protected float rating;

    public Product() {
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    // Getters and setters
   ...    

Book.java

public class Book extends Product{

    @JsonProperty("category")
    private String category;
    @JsonProperty("author")
    private String author;
    @JsonProperty("publicationDate")
    private Date publicationDate;
    @JsonProperty("numPage")
    private int numPage;

    public Book() {
    }
    // Getters and setters   
   ...

Can you help me figure it out how can I properly serialize the ObjectId to JSON?

1条回答
forever°为你锁心
2楼-- · 2019-04-17 02:07

It looks like Jackson has been customized to serialize the string id field in a special way. That is probably a part of the integration with org.bson library.

The problem is that your deserializer is parametrized by the ObjectId type instead of String or plain Object. Try to change it as follows and also remove the @ObjectId annotation from the field declaration. Here is an example:

public class ObjectIdSerializer extends JsonSerializer<Object> {
    @Override
    public void serialize(Object value, JsonGenerator jsonGen,SerializerProvider provider) throws IOException {
        jsonGen.writeString(value.toString());
    }
}

You may also consider adopting the Jackson-Jongo provider class to fix the object id serialization for all the classes.

查看更多
登录 后发表回答