从Gson移植到Jackson,混淆了泛型和定制反序列化器

时间:2014-09-24 21:25:45

标签: android json jackson gson json-deserialization

我们正在尝试评估杰克逊作为Gson的替代方案,并且我遇到了理解泛型的问题。我觉得这是一个简单的问题,我完全错过了答案,并没有通过谷歌或文档找到示例/信息。我希望有人可以指出我的错误或指出我正确的实施。

说我有这样的课程:

public class Response<T extends BaseTypeInterface > implements BaseTypeInterface {
    private Meta meta;
    private T mResult;
    private Group<Notification> notifications;
}

我想为它制作一个自定义序列化程序,但我做的任何事都不会让我在反序列化器中获得类型T信息。 理论上我想做SimpleModule.addDeserializer(Response.class, new ResponseV2Serializer<BaseTypeInterface>()); 然后在反序列化器中,我想读取从ObjectMapper.readValue(string, TypeReference<Response<SomeClassExtBaseTypeInterface>)传递的类型信息。

使用我当前的自定义反序列化器,我实现了ContextualDeserializer,希望从BeanProperty中提取类型信息,但每次调用BeanProperty时都是空的。

public static class ResponseSerializer<T extends BaseTypeType>
        extends JsonDeserializer<Response<T>>
        implements ContextualDeserializer {

    @Override
    public ResponseV2<T> deserialize(JsonParser jp, DeserializationContext ctxt)
        throws IOException, JsonProcessingException {
        return null;
    }
    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) 
        throws JsonMappingException {
        return this;
    }
}

示例Json看起来像这样:

{
    meta: {
        code: 200,
        requestId: "541fb2dc498e306d526f7e4c"
    },
    response: {
        //content
    }
}

1 个答案:

答案 0 :(得分:0)

阅读你的问题和需求,我不知道你想要有几个datarepresentations并改变它。例如,响应可以将列表遗留一些,并根据请求重新计算另一个时间。如果这是你想要做的,我认为你可以直接找到解决方案:

  • 响应1:根据需要格式化
  • 回应2:呈现动物清单

我们使用遗产来解决您的问题。 此解决方案的优点是您不需要编写序列化/反序列化器。尽量避免这样做:它的错误和容易出错......并且通常会导致缓慢/复杂的序列化。 :)

package com.rizze.labs;

import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.ArrayList;

import org.junit.Test;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.databind.ObjectMapper;

    /**
     * 
     * @author je@rizze.com
     *
     */

    public class SOFW26026792 {


        @Test
    public void fromJsonToJackson() throws IOException{

        TheBean bean = new TheBean();
        ObjectMapper mapper = new ObjectMapper();

        //toJson
        String beanJson=mapper.writeValueAsString(bean);
        System.out.println("Response1 "+beanJson);

        //fromJson
        TheBean beanCopy = mapper.readValue(beanJson, TheBean.class);
        assertTrue(bean.meta.requestId.equals(beanCopy.meta.requestId));
        System.out.println("Response1 is OK");
    }


    @Test
    public void response2() throws IOException{

        TheBean2 animals = new TheBean2();
        animals.fillDatas();

        ObjectMapper mapper = new ObjectMapper();

        //toJson
        String animalsJson=mapper.writeValueAsString(animals);
        System.out.println("Response2 (Animals Response) "+animalsJson);

        //fromJson
        TheBean2 animalsCopy = mapper.readValue(animalsJson, TheBean2.class);
        assertTrue(animals.meta.requestId.equals(animalsCopy.meta.requestId));
        System.out.println("Response2 (Animals Response) is OK");
    }



    public static class TheBean{
        public RRMeta meta ;        
        public Object response; 

        public TheBean(){
            meta = new RRMeta();
            response = new RResponse();
            meta.code=200;
            meta.requestId="id:12312342325252345234234";
        }

    }


    public static class RRMeta{
        public int code;
        public String requestId;
        public RRMeta(){

        }
    }

    public static class TheBean2 extends TheBean{

        public TheBean2(){
            meta = new RRMeta();
            response = new RResponseAnimals();
        }
        public void fillDatas(){

            meta.code=200;
            meta.requestId="id:animal:4";

            ((RResponseAnimals)response).fillDatas();
        }
    }

    public static class RResponse{

        public String val1;
        public String val2;

        public RResponse(){
            val1="example";
            val2="yummi";

        }
    }   



    public static class RResponseAnimals {

        public ArrayList<String> animals= new ArrayList<String>();

        public RResponseAnimals addAnimal(String animal ){
            if(animals == null)animals=new ArrayList<String>();
            animals.add(animal);
            return this;
        }

        public RResponseAnimals(){}

        public void fillDatas(){
            addAnimal("snow monkey")
            .addAnimal("royal ant")
            .addAnimal("pink panther")
            .addAnimal("Blue elephant");
        }
    }   



}

以下是执行此junits的控制台输出:

Response1 {"meta":{"code":200,"requestId":"id:12312342325252345234234"},"response":{"val1":"example","val2":"yummi"}}
    Response1 is OK
    Response2 (Animals Response) {"meta":{"code":200,"requestId":"id:animal:4"},"response":{"animals":["snow monkey","royal ant","pink panther","Blue elephant"]}}
    Response2 (Animals Response) is OK 

要点完整代码: https://gist.github.com/jeorfevre/c0b4674a6a6bcd82630f