【问题标题】:Apache commons MultiValuedMap and JacksonApache commons MultiValuedMap 和 Jackson
【发布时间】:2021-02-24 13:03:21
【问题描述】:

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

这是我的代码 sn-p 导入 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, gen, provider);
        }
      } else if(){....} else if(){....} ...
    }
    gen.writeEndObject();
  }
}

【问题讨论】:

    标签: java jackson apache-commons fasterxml


    【解决方案1】:

    您可以使用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 ]
      }
    }
    

    【讨论】:

    • 多重地图的目的是为了拥有某物。比如'{"json-with-multiple-identical-keys":{"key1":"value1","key1":"value2","key2":true}}'。这就是 MultiValuedMap.asMap() 不适合的原因,因为它是 Map>.
    • @hiaclibe, JSON 有两个或多个同名字段,这不是一个好主意。许多库,包括Jackson,都需要自定义处理。 JSON Array 看起来更自然。但是,我知道对方可能会强制使用这样的格式。我们需要自定义Map serialiser 来处理这种情况。
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 2015-01-17
    • 2011-01-21
    • 2023-03-30
    • 2020-02-06
    • 2018-01-02
    • 2018-04-04
    • 1970-01-01
    相关资源
    最近更新 更多