使用Moxy进行通用的Map<String, Object> JSON编组和解组

3
有没有办法使用Moxy将Map转换为JSON,以便结果使用JSON的自然结构? 也就是说,键是字符串,对于所有可能的值遵循以下规则(可能不完整): < ul>
  • 数字(例如Integer)成为JSON数字(如果太大,则为字符串)
  • 字符串变成JSON字符串
  • 集合,数组,Iterable变成JSON数组
  • 最后,对于Map,递归应用相同的规则
  • 任何其他对象都以自然的Moxy方式编组

    已经有一个示例演示如何使用@XmlVariableNode(请参见http://blog.bdoughan.com/2013/06/moxys-xmlvariablenode-using-maps-key-as.html?m=1)来编排Map<String,Integer>和其他特定的映射,但是我无法将这个想法扩展到也可以将子类型插入为值。

    请注意,Moxy应该能够将JSON解组回原始映射。

    Jackson默认情况下可以执行此操作。

  • 1个回答

    4

    我尝试使用JAXB RI(XML)来实现您想要的类似功能:

    @XmlRootElement
    public class Foo {
        @XmlJavaTypeAdapter(MapAdapter.class)
        public Map<String, Object> map;
    }
    
    public class MapAdapter extends XmlAdapter<MapEntry[], Map<String, Object>> {
        @Override
        public Map<String, Object> unmarshal(MapEntry[] v) throws Exception {
            Map<String, Object> map = new HashMap<>();
            for (MapEntry me : v)
                map.put(me.key, me.value);
            return map;
        }
        @Override
        public MapEntry[] marshal(Map<String, Object> v) throws Exception {
            MapEntry[] mes = new MapEntry[v.size()];
            int i = 0;
            for (Map.Entry<String, Object> entry : v.entrySet())
                mes[i++] = new MapEntry(entry.getKey(), entry.getValue());
            return mes;
        }
    }
    
    public class MapEntry {
        public String key;
        public Object value;
    
        public MapEntry() {}
    
        public MapEntry(String key, Object value) {
            this.key = key;
            this.value = value;
        }
    }
    

    很不幸,MOXy存在一些问题(https://bugs.eclipse.org/bugs/show_bug.cgi?id=465014),无法处理此内容。

    如果您需要使用MOXy,则必须使用Blaise博客中描述的方法:

    @XmlRootElement
    public class MoxyFoo {
        @XmlJavaTypeAdapter(MoxyMapAdapter.class)
        public Map<String, Object> map = new HashMap<>();
    }
    
    public class MoxyMapAdapter extends XmlAdapter<MoxyMapAdapter.AdaptedMap, Map<String, Object>> {
        @Override
        public AdaptedMap marshal(Map<String, Object> map) throws Exception {
            AdaptedMap adaptedMap = new AdaptedMap();
            for (Entry<String, Object> entry : map.entrySet()) {
                AdaptedEntry adaptedEntry = new AdaptedEntry();
                adaptedEntry.key = entry.getKey();
                adaptedEntry.value = entry.getValue();
                adaptedMap.entries.add(adaptedEntry);
            }
            return adaptedMap;
        }
        @Override
        public Map<String, Object> unmarshal(AdaptedMap adaptedMap) throws Exception {
            List<AdaptedEntry> adaptedEntries = adaptedMap.entries;
            Map<String, Object> map = new HashMap<>(adaptedEntries.size());
            for (AdaptedEntry adaptedEntry : adaptedEntries) {
                map.put(adaptedEntry.key, adaptedEntry.value);
            }
            return map;
        }
    
        public static class AdaptedMap {
            @XmlVariableNode("key")
            List<AdaptedEntry> entries = new ArrayList<>();
        }
    
        public static class AdaptedEntry {
            @XmlTransient
            public String key;
            @XmlValue
            public Object value;
        }
    }
    

    对于XML来说它能正常工作,但对于JSON来说只有编组(marshalling)功能正常,我已提交了一个缺陷报告以修复反编组(unmarshalling)问题:https://bugs.eclipse.org/bugs/show_bug.cgi?id=465016


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接