Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于使用Jackson将JSON映射到不同类型映射的ContextualDeserializer_Json_Generics_Mapping_Jackson - Fatal编程技术网

用于使用Jackson将JSON映射到不同类型映射的ContextualDeserializer

用于使用Jackson将JSON映射到不同类型映射的ContextualDeserializer,json,generics,mapping,jackson,Json,Generics,Mapping,Jackson,此JSON片段应映射到Java对象,该对象包含cars类型的Map字段和bikes类型的Map字段。因为自行车和汽车在JSON文件中可以是空字符串,所以我需要一个自定义反序列化器() 我考虑使用一个通用自定义反序列化器的实例,它可以由基于BeanProperty参数的ContextualDeserializer方法的CreateContextent(反序列化配置cfg,BeanProperty属性)返回。通用自定义反序列化程序如下所示: public class MapsGenericDeser

此JSON片段应映射到Java对象,该对象包含
cars
类型的
Map
字段和
bikes
类型的
Map
字段。因为自行车和汽车在JSON文件中可以是空字符串,所以我需要一个自定义反序列化器()

我考虑使用一个通用自定义反序列化器的实例,它可以由基于BeanProperty参数的
ContextualDeserializer
方法的
CreateContextent(反序列化配置cfg,BeanProperty属性)
返回。通用自定义反序列化程序如下所示:

public class MapsGenericDeserializer<T> extends
        JsonDeserializer<Map<String, T>> {

    private ObjectMapper mapper; // ObjectMapper without special map deserializer

    public MapsGenericDeserializer(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public Map<String, T> deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectCodec codec = jp.getCodec();
        JsonNode node = codec.readTree(jp);
        if (!"".equals(node.getTextValue())) {
            return mapper.readValue(node, 
                    new TypeReference<Map<String, T>>() {});
        }
        return null; // Node was an empty string
    }
}
公共类MapsGenericDeserializer扩展
JsonDeserializer{
私有对象映射器映射器;//不带特殊映射反序列化器的对象映射器
公共映射通用反序列化器(ObjectMapper映射器){
this.mapper=mapper;
}
@凌驾
公共映射反序列化(JsonParser jp,反序列化上下文ctxt)
抛出IOException、JsonProcessingException{
ObjectCodec codec=jp.getCodec();
JsonNode=codec.readTree(jp);
如果(!“”.equals(node.getTextValue())){
返回mapper.readValue(节点,
新类型引用(){});
}
return null;//节点为空字符串
}
}
下面的上下文序列化程序无法工作,因为无法从
MapsGenericDeserializer
转换为
JsonDeserializer
。也许这在较新版本的Java中是可能的,但在我编写代码的Android版本中不起作用。那么,我如何实现期望的行为呢

public class MapsDeserializer extends JsonDeserializer<Map<String, ?>>
        implements ContextualDeserializer<Map<String, ?>> {

    private ObjectMapper mapper;

    MapsGenericDeserializer<Car> carDeserializer = new MapsGenericDeserializer<Car>(mapper);
    MapsGenericDeserializer<Bike> bikeDeserializer = new MapsGenericDeserializer<Bike>(mapper);

    public MapsDeserializer(ObjectMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public JsonDeserializer<Map<String, ?>> createContextual(DeserializationConfig cfg,
            BeanProperty property) throws JsonMappingException {

        Class<?> targetClass = property.getType().containedType(1).getRawClass();

        if(targetClass.equals(Car.class) { 
            return carDeserializer; // Type mismatch!
        } else if (targetClass.equals(Bike.class)) {
            return bikeDeserializer; // Type mismatch!
        } else {
            return this;
        }
    }

    // ...
}
公共类MapsDeserializer扩展JsonDeserializer
实现ContextualDeserializer{
私有对象映射器映射器;
MapsGenericDeserializer CardSerializer=新的MapsGenericDeserializer(映射器);
MapsGenericDeserializer bikeDeserializer=新的MapsGenericDeserializer(映射器);
公共映射序列化程序(ObjectMapper映射器){
this.mapper=mapper;
}
@凌驾
公共JsonDeserializer createContext(反序列化配置cfg,
BeanProperty属性)引发JsonMappingException{
类targetClass=property.getType().containedType(1.getRawClass();
如果(targetClass.equals)等于(Car.class){
return carDeserializer;//类型不匹配!
}else if(targetClass.equals(Bike.class)){
return bikeDeserializer;//类型不匹配!
}否则{
归还这个;
}
}
// ...
}

以下是我可能的方法

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.BeanProperty;
import org.codehaus.jackson.map.ContextualDeserializer;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.module.SimpleModule;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    EmptyStringAsMapDeserializer<Map<String, ?>> emptyStringAsMapDeserializer = 
        new EmptyStringAsMapDeserializer<Map<String, ?>>(null, new ObjectMapper());

    SimpleModule module = new SimpleModule("ThingsDeserializer", Version.unknownVersion());
    module.addDeserializer(Map.class, emptyStringAsMapDeserializer);

    ObjectMapper mapper = new ObjectMapper().withModule(module);

    Person person = mapper.readValue(new File("input.json"), Person.class);
    System.out.println(mapper.writeValueAsString(person));
  }
}

class Person
{
  public int id;
  public String name;
  public Map<String, Car> cars;
  public Map<String, Bike> bikes;
}

class Car
{
  public String color;
  public String buying_date;
}

class Bike
{
  public String color;
}

class EmptyStringAsMapDeserializer<T>
    extends JsonDeserializer<Map<String, ?>>
    implements ContextualDeserializer<Map<String, ?>>
{
  private Class<?> targetType;
  private ObjectMapper mapper;

  EmptyStringAsMapDeserializer(Class<?> targetType, ObjectMapper mapper)
  {
    this.targetType = targetType;
    this.mapper = mapper;
  }

  @Override
  public JsonDeserializer<Map<String, ?>> createContextual(DeserializationConfig config, BeanProperty property)
      throws JsonMappingException
  {
    return new EmptyStringAsMapDeserializer<Object>(property.getType().containedType(1).getRawClass(), mapper);
  }

  @Override
  public Map<String, ?> deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException
  {
    JsonNode node = jp.readValueAsTree();
    if ("".equals(node.getTextValue()))
      return new HashMap<String, Object>();
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(node, mapper.getTypeFactory().constructMapType(Map.class, String.class, targetType));
  }
}
导入java.io.File;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
导入org.codehaus.jackson.JsonNode;
导入org.codehaus.jackson.JsonParser;
导入org.codehaus.jackson.JsonProcessingException;
导入org.codehaus.jackson.Version;
导入org.codehaus.jackson.map.BeanProperty;
导入org.codehaus.jackson.map.ContextualDeserializer;
导入org.codehaus.jackson.map.DeserializationConfig;
导入org.codehaus.jackson.map.DeserializationContext;
导入org.codehaus.jackson.map.jsonderializer;
导入org.codehaus.jackson.map.JsonMappingException;
导入org.codehaus.jackson.map.ObjectMapper;
导入org.codehaus.jackson.map.module.SimpleModule;
公开课Foo
{
公共静态void main(字符串[]args)引发异常
{
EmptyStringAsMapDeserializer EmptyStringAsMapDeserializer=
新的EmptyStringAsMapDeserializer(null,新的ObjectMapper());
SimpleModule=new SimpleModule(“ThingsDeserializer”,Version.unknownVersion());
module.addDeserializer(Map.class,emptyStringAsMapDeserializer);
ObjectMapper mapper=new ObjectMapper().withModule(模块);
Person=mapper.readValue(新文件(“input.json”)、Person.class);
System.out.println(mapper.writeValueAsString(person));
}
}
班主任
{
公共int id;
公共字符串名称;
公共地图车;
公共地图自行车;
}
班车
{
公共字符串颜色;
公开字符串购买日期;
}
职业自行车
{
公共字符串颜色;
}
类EmptyStringAsMapDeserializer
扩展JsonDeserializer
实现ContextualDeserializer
{
私有类targetType;
私有对象映射器映射器;
EmptyStringAsMapDeserializer(类targetType,对象映射器映射器)
{
this.targetType=targetType;
this.mapper=mapper;
}
@凌驾
公共JsonDeserializer createContext(反序列化配置,BeanProperty属性)
抛出JsonMappingException
{
返回新的EmptyStringAsMapDeserializer(属性.getType().containedType(1).getRawClass(),映射器);
}
@凌驾
公共映射反序列化(JsonParser jp,反序列化上下文ctxt)
抛出IOException、JsonProcessingException
{
JsonNode=jp.readValueAsTree();
如果(“.equals(node.getTextValue()))
返回新的HashMap();
ObjectMapper mapper=新的ObjectMapper();
返回mapper.readValue(节点,mapper.getTypeFactory().constructMapType(Map.class,String.class,targetType));
}
}

泛型类型参数可能有点乱。我做了一点快速复制粘贴。

我如何使用这样一个带注释的反序列化程序?
@JsonDeserializer(?)public void setBikes(List bikes)
我建议发布一个新问题。抱歉,我单独添加了我的问题:,
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.map.BeanProperty;
import org.codehaus.jackson.map.ContextualDeserializer;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.module.SimpleModule;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    EmptyStringAsMapDeserializer<Map<String, ?>> emptyStringAsMapDeserializer = 
        new EmptyStringAsMapDeserializer<Map<String, ?>>(null, new ObjectMapper());

    SimpleModule module = new SimpleModule("ThingsDeserializer", Version.unknownVersion());
    module.addDeserializer(Map.class, emptyStringAsMapDeserializer);

    ObjectMapper mapper = new ObjectMapper().withModule(module);

    Person person = mapper.readValue(new File("input.json"), Person.class);
    System.out.println(mapper.writeValueAsString(person));
  }
}

class Person
{
  public int id;
  public String name;
  public Map<String, Car> cars;
  public Map<String, Bike> bikes;
}

class Car
{
  public String color;
  public String buying_date;
}

class Bike
{
  public String color;
}

class EmptyStringAsMapDeserializer<T>
    extends JsonDeserializer<Map<String, ?>>
    implements ContextualDeserializer<Map<String, ?>>
{
  private Class<?> targetType;
  private ObjectMapper mapper;

  EmptyStringAsMapDeserializer(Class<?> targetType, ObjectMapper mapper)
  {
    this.targetType = targetType;
    this.mapper = mapper;
  }

  @Override
  public JsonDeserializer<Map<String, ?>> createContextual(DeserializationConfig config, BeanProperty property)
      throws JsonMappingException
  {
    return new EmptyStringAsMapDeserializer<Object>(property.getType().containedType(1).getRawClass(), mapper);
  }

  @Override
  public Map<String, ?> deserialize(JsonParser jp, DeserializationContext ctxt)
      throws IOException, JsonProcessingException
  {
    JsonNode node = jp.readValueAsTree();
    if ("".equals(node.getTextValue()))
      return new HashMap<String, Object>();
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(node, mapper.getTypeFactory().constructMapType(Map.class, String.class, targetType));
  }
}