Apache Commons MultiValuedMap 和 Jackson

问题描述

我想序列化/反序列化 MultiValuedMap。很难相信,www 中没有示例代码。有谁知道一个例子?

这是我的代码片段 导入 org.apache.commons.collections4.MultiValuedMap;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

public class MultiValuedMapSerializer extends StdSerializer<MultiValuedMap<String,Object>> {
  private static final long serialVersionUID = 1L;

  public MultiValuedMapSerializer() {
    this(null);
  }

  protected MultiValuedMapSerializer(Class<MultiValuedMap<String,Object>> klass) {
    super(klass);
  }

  @Override
  public void serialize(MultiValuedMap<String,Object> value,JsonGenerator gen,SerializerProvider provider) throws IOException {
    gen.writeStartObject();
    for (Entry<String,Object> entry : value.entries()) {
      if(entry.getValue() instanceOf MultiValuedMap){
        @SuppressWarnings("unchecked")
        MultiValuedMap<String,Object> map = (MultiValuedMap<String,Object>) value;
        if (key != null) {
          gen.writeFieldName(key);
          serialize(map,gen,provider);
        } else {
          serialize(map,provider);
        }
      } else if(){....} else if(){....} ...
    }
    gen.writeEndobject();
  }
}

解决方法

您可以使用 org.apache.commons.collections4.MultiValuedMap 可以轻松转换为 Map 的事实。 Jackson 已经有一个序列化程序,因此所有极端情况都会自动处理。它可能如下所示:

class MultiValuedMapJsonSerializer extends JsonSerializer<MultiValuedMap> {
    @Override
    public void serialize(MultiValuedMap value,JsonGenerator gen,SerializerProvider serializers) throws IOException {
        if (value == null) {
            gen.writeNull();
            return;
        }

        gen.writeObject(value.asMap());
    }

    @Override
    public Class<MultiValuedMap> handledType() {
        return MultiValuedMap.class;
    }
}

您可以在下面找到如何注册和使用的示例:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.collections4.MultiValuedMap;
import org.apache.commons.collections4.multimap.HashSetValuedHashMap;

import java.io.IOException;

public class JsonMultiValuedMapApp {

    public static void main(String[] args) throws IOException {
        SimpleModule collections4Module = new SimpleModule();
        collections4Module.addSerializer(new MultiValuedMapJsonSerializer());

        ObjectMapper mapper = JsonMapper.builder()
                .enable(SerializationFeature.INDENT_OUTPUT)
                .addModule(collections4Module)
                .build();

        MapWrapper wrapper = new MapWrapper();
        wrapper.getMap().put("numbers",1L);
        wrapper.getMap().put("numbers",2L);
        wrapper.getMap().put("strings","value");

        mapper.writeValue(System.out,wrapper);
    }
}

class MapWrapper {

    private MultiValuedMap<String,Object> map = new HashSetValuedHashMap<>();

    public MultiValuedMap<String,Object> getMap() {
        return map;
    }

    public void setMap(MultiValuedMap<String,Object> map) {
        this.map = map;
    }
}

以上代码打印:

{
  "map" : {
    "strings" : [ "value" ],"numbers" : [ 1,2 ]
  }
}