如何将杰克逊自定义值序列化程序用于 Map<String、Object>?



i具有Map<String, Object>形式的DB的结果集,我应该从静止服务中返回为json。地图中的值可能是各种类型的,包括PGObjectStringIntegerDate

,我用类型为" JSONB"为org.postgresql.util.PGObject类编写了一个自定义序列化器,该类别在List<?>中正常工作,但在Map<String, Object>中不行。

public class PgObjectSerializer extends JsonSerializer<PGobject>{
    @Override
    public void serialize(PGobject pgObject, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        switch (pgObject.getType()) {
            case "json":
            case "jsonb":
                gen.writeRawValue(pgObject.getValue());
                break;
            default:
                gen.writeString(pgObject.getValue());
        }
    }
}

目标pgobject看起来像这样:

PGObject pgo = new PGObject();
pgo.setType("jsonb");
pgo.setValue("[{"id": 6, "name": "Foo"}, {"id": 7, "name": "Bar"}, {"id": 8, "name": "Baz"}]"); map.put("reason", pgo);

当杰克逊在 Map<String, Object>中序列化此 PGObject值时,我得到的 json值如下:

  "reason": {
    "type": "jsonb",
    "value": "[{"id": 6, "name": "Foo"}, {"id": 7, "name": "Bar"}, {"id": 8, "name": "Baz"}]"
  }

我需要的:

  "reason": [
    {
      "id": 6,
      "name": "Foo"
    },
    {
      "id": 7,
      "name": "Bar"
    },
    {
      "id": 8,
      "name": "Baz"
    },
  ],

我尝试将模块添加到ObjectMapper和自定义MapTypeObjectWriter,如序列化MAP&lt;日期的答案所示,String&gt;与杰克逊:

@Service
@Transactional
public class MyClass {
    private final ObjectWriter writer;
    private final MyRepo repository;
    @Autowired
    public MyClass(MyRepo repository) {
        this.repository = repository;
        SimpleModule module = new SimpleModule();
        module.addKeySerializer(PGobject.class, new PgObjectSerializer());
        ObjectMapper mapper = new ObjectMapper();
        JavaType myMapType = mapper.getTypeFactory().
                constructMapType(HashMap.class, String.class, PGobject.class);
        writer = mapper.registerModule(module).writerFor(myMapType);
    }
    ...
    private String toJsonString(Map<String, Object> map) {
        try {
            return writer.writeValueAsString(map);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}

但是我会为地图中的每个非PGObject对象遇到序列化错误:

[Test worker] ERROR 
com.fasterxml.jackson.databind.JsonMappingException: object is not an instance of declaring class (through reference chain: java.util.HashMap["end_date"]->java.lang.String["type"])
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:388)
    at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:348)
    at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:343)
    at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:698)
    at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
    at com.fasterxml.jackson.databind.ser.std.MapSerializer.serializeFieldsUsing(MapSerializer.java:736)
    at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:534)
    at com.fasterxml.jackson.databind.ser.std.MapSerializer.serialize(MapSerializer.java:30)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:416)
    at com.fasterxml.jackson.databind.ObjectWriter$Prefetch.serialize(ObjectWriter.java:1425)
    at com.fasterxml.jackson.databind.ObjectWriter._configAndWriteValue(ObjectWriter.java:1158)
    at com.fasterxml.jackson.databind.ObjectWriter.writeValueAsString(ObjectWriter.java:1031)

当在 Map<String, Object>序列化过程中找到pgobject的值时,如何在杰克逊中启用我的PGObjectSerializer

一个工作可以是为Object添加序列化器。

然后在序列化器本身中,您可以检查对象是否为PGobject的实例。

,在mymaptype中,您可以指定Object.class

JavaType myMapType = mapper.getTypeFactory().
                constructMapType(HashMap.class, String.class, Object.class);

序列化器将是:

class PgObjectSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object object, JsonGenerator gen, SerializerProvider serializers) throws IOException {
    if (object instanceof PGobject) {
        PGobject pgObject = (PGobject) object;
        switch (pgObject.getType()) {
        case "json":
        case "jsonb":
            gen.writeRawValue(pgObject.getType());
            break;
        default:
            gen.writeString(pgObject.getType());
        }
    } else {
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(gen, object);
    }
}

相关内容

最新更新