Как сериализовать ObjectId в JSON?

Я хочу сериализовать ObjectId моего класса Product в JSON. Я получил следующий 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}]

Вы можете заметить, что "_id" не был правильно сериализован, это должно быть "539da7a6370882f10d5c2777" (с двойными кавычками), а не просто 539da7a6370882f10d5c2777.

Поэтому я попытался реализовать свой собственный ObjectIdSerializer следующим образом:

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());
    }
}

Это дало мне другую ошибку: java.lang.String cannot be cast to org.bson.types.ObjectId (through reference chain: models.Book["_id"])

Вот мой класс Product и класс Book:

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   
   ...

Можете ли вы помочь мне понять, как правильно сериализовать ObjectId в JSON?


person lvarayut    schedule 15.06.2014    source источник


Ответы (1)


Похоже, Джексон был настроен для сериализации поля идентификатора строки особым образом. Вероятно, это часть интеграции с org.bson библиотекой.

Проблема в том, что ваш десериализатор параметризован типом ObjectId вместо String или простого Object. Попробуйте изменить его следующим образом, а также удалите аннотацию @ObjectId из объявления поля. Вот пример:

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

Вы также можете принять класс провайдера Jackson-Jongo, чтобы исправить сериализацию идентификатора объекта для всех классов. .

person Alexey Gavrilov    schedule 15.06.2014
comment
Спасибо за ответ. Это почти идеально, за исключением того, что сериализованный _id немного странный, _id:\539df7793708be9becea990e\. Более того, _id в моей MongoDB изменилось с "_id" : ObjectId("539e06e03708a8e88421cf6d") на "_id":"539e06e03708a8e88421cf6d". Есть ли способ решить эту проблему? - person lvarayut; 16.06.2014
comment
Можете ли вы попробовать удалить аннотацию ObjectId? Я обновил свой ответ по этому поводу. - person Alexey Gavrilov; 16.06.2014
comment
Оно работало завораживающе! Не могли бы вы немного объяснить, почему это работает, удалив ObjectId? Без ObjectId будет ли какое-либо влияние на мой класс в будущем? - person lvarayut; 16.06.2014
comment
Интересно, что произойдет, если вы просто удалите аннотацию ObjectId и JsonDeserialize? - person Alexey Gavrilov; 16.06.2014
comment
У меня есть "_id" : "539e9c70ccf270420d3e96a8", однако я не знаю, хорошо ли хранить _id как строку вместо ObjectId. - person lvarayut; 16.06.2014
comment
Я новичок в Spring. Куда добавить этот класс? Требуется ли аннотация @Configuration? Спасибо. - person zookastos; 29.04.2020