簡體   English   中英

嘗試將自定義通用gson反序列化器遷移到jackson

[英]Trying to migrate custom generic gson deserializer to jackson

目前正在使用GSON進行反序列化並使用改造GsonConverterFactory進行改造:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(new TypeToken<Map<Book, Collection<Author>>>(){}.getType(), new BooksDeserializer(context));
Gson gson = gsonBuilder.create();

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(url)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build();

BookService service = retrofit.create(BookService.class);
Response<Map<Book, Collection<Author>>> response = service.getBooks().execute();    

我想使用改造提供的JacksonConverterFactory? 我需要提供傑克遜映射器。 有沒有辦法像我使用GSON一樣向該映射器提供類型信息?

SimpleModule simpleModule = new SimpleModule();
// TODO provide mapper with info needed to deserialize 
// Map<Book, Collection<Author>>
mapper.registerModule(simpleModule);

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl(url)
    .addConverterFactory(JacksonConverterFactory.create(mapper))
    .build();

BookService service = retrofit.create(BookService.class);
Response<Map<Book, Collection<Author>>> response = service.getBooks().execute();

具體看TODO,我可以告訴映射器使用這個解串器嗎?

public class BooksDeserializer extends JsonDeserializer<Map<Book, Collection<Author>>> {

    @Override
    public Map<Book, Collection<Author>> deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
        // deserialize here
    }
}

根據APISimpleModule.addDeserializer(java.lang.Class, com.fasterxml.jackson.databind.JsonSerializer)需要一個JsonSerializer<T>的實例,其中T是您作為參數提供的類的超類型 ,即解串器需要能夠反序列化作為提供的類的子類的對象; TypeReference<Map<Book, Collection<Author>>> 不是 Map<Book, Collection<Author>>的子類型。

但是,由於Java的類型擦除,為地圖編寫序列化器並不容易。 一種方法是為地圖編寫一個包裝類,例如

@XmlRootElement
public class SerializableBookMapWrapper {

    private Map<Book, Collection<Author>> wrapped;

    public SerializableBookMapWrapper(final Map<Book, Collection<Author>> wrapped) {
        this.wrapped = wrapped;
    }

    public Map<Book, Collection<Author>> getWrapped() {
        return wrapped;
    }

    public void setWrapped(final Map<Book, Collection<Author>> wrapped) {
        this.wrapped = wrapped;
    }
}

使用這種包裝類,您可以實現JsonDeserializer<SerializableBookMapWrapper>並使用它。 但是,如果您沒有在Book and Author的定義中使用Jackson注釋 ,則還需要為它們提供自定義反序列化器

或者,您也可以嘗試提供此類型信息,同時實際使用ObjectMapper實例進行反序列化

我認為這里存在誤解:你沒有實現JsonDeserializer只是因為你想綁定到某種類型。 這就是傑克遜本身所做的。 如果由於某種原因需要定制的反序列化器(或序列化器),它只會處理嵌套類型的特定部分; 用於BookAuthorMap反序列化器,但用於嵌套類型Map deserializer委托給鍵和值處理程序。 它沒有注冊組合。

無論如何:我相當確定自定義反序列化器不是這里的答案,而是一種將ObjectMapper基本用法包裝為讀取給定類型的JSON的方法。 但是,如果不了解更多關於Retrofit的信息,我不知道究竟是什么。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM