Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.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

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
Java Jackson序列化和反序列化Map<;字符串,字节[]>;_Java_Json_Jackson - Fatal编程技术网

Java Jackson序列化和反序列化Map<;字符串,字节[]>;

Java Jackson序列化和反序列化Map<;字符串,字节[]>;,java,json,jackson,Java,Json,Jackson,使用Jackson对映射进行序列化和反序列化的正确方法是什么 我一直在这样做: byte[] toPostgres = OBJECT_MAPPER.writeValueAsBytes(context); 我创建了一个地图: 然后从博士后那里读到: Map<String, byte[]> fromPostgres = OBJECT_MAPPER.readValue(toPostgres, Map.class) 我得到以下错误: 感兴趣的部分: com.fasterxml.jacks

使用Jackson对映射进行序列化和反序列化的正确方法是什么

我一直在这样做:

byte[] toPostgres = OBJECT_MAPPER.writeValueAsBytes(context);
我创建了一个
地图

然后从博士后那里读到:

Map<String, byte[]> fromPostgres = OBJECT_MAPPER.readValue(toPostgres, Map.class)
我得到以下错误:

感兴趣的部分:

com.fasterxml.jackson.databind.JsonMappingException: class java.lang.String cannot be cast to class [B (java.lang.String and [B are in module java.base of loader 'bootstrap') (through reference chain: com.amce.MyMessage["context"]->java.util.LinkedHashMap["outer-key"])
"exception":"java.lang.ClassCastException: class java.lang.String cannot be cast to class [B (java.lang.String and [B are in module java.base of loader 'bootstrap')
     at com.fasterxml.jackson.databind.ser.std.ByteArraySerializer.serialize(ByteArraySerializer.java:30)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFieldsUsing(MapSerializer.java:817)
     ... 23 common frames omitted
Wrapped by: com.fasterxml.jackson.databind.JsonMappingException: class java.lang.String cannot be cast to class [B (java.lang.String and [B are in module java.base of loader 'bootstrap') (through reference chain: com.amce.MyMessage[\"context\"]->java.util.LinkedHashMap[\"outer-key\"])
     at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:397)
     at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:356)
     at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFieldsUsing(MapSerializer.java:822)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:641)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:33)
     at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
     at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722)
     at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166)
     at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
     at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
     at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4110)
     at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsBytes(ObjectMapper.java:3437)
     at 
完全错误:

com.fasterxml.jackson.databind.JsonMappingException: class java.lang.String cannot be cast to class [B (java.lang.String and [B are in module java.base of loader 'bootstrap') (through reference chain: com.amce.MyMessage["context"]->java.util.LinkedHashMap["outer-key"])
"exception":"java.lang.ClassCastException: class java.lang.String cannot be cast to class [B (java.lang.String and [B are in module java.base of loader 'bootstrap')
     at com.fasterxml.jackson.databind.ser.std.ByteArraySerializer.serialize(ByteArraySerializer.java:30)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFieldsUsing(MapSerializer.java:817)
     ... 23 common frames omitted
Wrapped by: com.fasterxml.jackson.databind.JsonMappingException: class java.lang.String cannot be cast to class [B (java.lang.String and [B are in module java.base of loader 'bootstrap') (through reference chain: com.amce.MyMessage[\"context\"]->java.util.LinkedHashMap[\"outer-key\"])
     at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:397)
     at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:356)
     at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFieldsUsing(MapSerializer.java:822)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:641)
     at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:33)
     at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:727)
     at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:722)
     at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:166)
     at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
     at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
     at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:4110)
     at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsBytes(ObjectMapper.java:3437)
     at 
我在这篇帖子上找到了答案:

而不是:

Map<String, byte[]> fromPostgres = OBJECT_MAPPER.readValue(toPostgres, Map.class)
   byte[] toPostgres = OBJECT_MAPPER.writeValueAsBytes(context);
Map fromPostgres=OBJECT\u MAPPER.readValue(toPostgres,Map.class)
使用:

TypeReference typeRef
=新类型引用()
{
};
Map fromPostgres=OBJECT\u MAPPER.readValue(toPostgres,typeRef);

我只是想确定这是序列化和反序列化
映射的正确方法,其中
字节[]
数组可以是任何东西,例如另一个类等?

可能,当您从泛型类型保存数据时,您也会使用类型感知写入

而不是:

Map<String, byte[]> fromPostgres = OBJECT_MAPPER.readValue(toPostgres, Map.class)
   byte[] toPostgres = OBJECT_MAPPER.writeValueAsBytes(context);
使用:


其中,typeRef与数据恢复期间的值相同。

Jackson的
ObjectMapper
将数据转换为JSON或从JSON转换为JSON。JSON只有五种数据类型(字符串、数字、布尔值、对象和数组),但Java显然还有更多。Jackson序列化数据时类型信息丢失,然后在反序列化数据时必须猜测类型信息

Jackson将示例上下文内容序列化为:

{“a-context-key”:“a-context-value”}

由于值和键都是原始字符串,而JSON对象是Java映射的自然等价物,所以这很好。当被要求将值写入字节时,Jackson认为JSON的UTF-8编码是合适的

JSON没有字节数组的表示形式,因此Jackson使用Base-64对数据进行编码,将其转换为JSON字符串。因此,
上下文
如下所示:

  abstract static class MixInUnicodeBlock {
    @JsonCreator
    public static UnicodeBlock forName(String name) {
      return UnicodeBlock.forName(name);
    }

    @JsonValue
    public abstract String toString();
  }

  public void example() {
    ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    OBJECT_MAPPER.addMixIn(UnicodeBlock.class,MixInUnicodeBlock.class);
    System.out.println(OBJECT_MAPPER.writeValueAsString(UnicodeBlock.GREEK));
    System.out.println(OBJECT_MAPPER.readValue("\"GREEK\"",UnicodeBlock.class));
  }
{“外键”:“eyjhlwnvbnlehqta2v5ijoiys1jb250zxh0lxzhbhvlin0=“}

该值曾经是
字节[]
的事实将丢失

当Jackson被要求通过以下方式反序列化:

Map<String, byte[]> fromPostgres = OBJECT_MAPPER.readValue(toPostgres, Map.class)
允许在编译时指定键和值的类型,方法是生成一个匿名类,其嵌入的泛型信息与映射的键和值类型匹配

也可以在运行时使用Jackson的类型工厂完成:

Class<?> keyType = String.class;
Class<?> valueType = byte[].class;

JavaType mapType = OBJECT_MAPPER.getTypeFactory()
    .constructMapType(
        Map.class,
        keyType,
        valueType);
Map<String, byte[]> fromPostgres = OBJECT_MAPPER.readValue(toPostgres, mapType);
将失败,即使Jackson可以仅使用其名称成功地序列化和反序列化该类。在这种情况下,可以通过使用“混音”来告诉Jackson该怎么做,如下所示:

  abstract static class MixInUnicodeBlock {
    @JsonCreator
    public static UnicodeBlock forName(String name) {
      return UnicodeBlock.forName(name);
    }

    @JsonValue
    public abstract String toString();
  }

  public void example() {
    ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    OBJECT_MAPPER.addMixIn(UnicodeBlock.class,MixInUnicodeBlock.class);
    System.out.println(OBJECT_MAPPER.writeValueAsString(UnicodeBlock.GREEK));
    System.out.println(OBJECT_MAPPER.readValue("\"GREEK\"",UnicodeBlock.class));
  }
总之,为了成功地序列化
Map

  • 如果这是根值,则需要提供缺少的通用信息。
    • 您可以在编译时使用
      TypeReference
      来存储通用信息
    • 您可以使用
      TypeFactory
      创建
      JavaType
      实例,从而允许在运行时指定它
  • 如果映射是类的属性,则将保留泛型信息,并且可能不需要进一步指定
  • 一个类可能需要直接注释,或者通过一个mix-in来成功处理
  • 为了精确控制序列化和反序列化,有时需要自定义序列化程序或反序列化程序

您是否尝试过将字节[]转换为Base64字符串,并使用它?
  abstract static class MixInUnicodeBlock {
    @JsonCreator
    public static UnicodeBlock forName(String name) {
      return UnicodeBlock.forName(name);
    }

    @JsonValue
    public abstract String toString();
  }

  public void example() {
    ObjectMapper OBJECT_MAPPER = new ObjectMapper();
    OBJECT_MAPPER.addMixIn(UnicodeBlock.class,MixInUnicodeBlock.class);
    System.out.println(OBJECT_MAPPER.writeValueAsString(UnicodeBlock.GREEK));
    System.out.println(OBJECT_MAPPER.readValue("\"GREEK\"",UnicodeBlock.class));
  }