使用每个属性的回调将JSON反序列化为Map <String,Object> - java

我想将任意JSON反序列化为Map<String, Object>。此映射的值可以是某些原始值(例如IntegerStringLocalDate,...),也可以是其他Map<String, Object>(递归)。

要获取原语,应为每个属性调用某种自定义客户端回调。根据密钥,将发生某些反序列化。例如(伪代码):

{
    "name": "Bill",
    "age": 53,
    "timestamp": "2012-04-23T18:25:43.511Z",
    "coordinates": "51.507351;-0.127758",
    "address": {
        "street": "Wallstreet",
        "city": "NY"
    }
}

Object convert(key, value) {
     if ("name".equals(key)) {
          return value.toString();
     } else if ("timestamp".equals(key)) {
          return LocalDate.parse(value);
     } else if ("coordinates".equals(key)) {
          return Coordinates.parse(value);
     }
     ...
}

在SO Jackson - Recursive parsing into Map<String, Object>中,提供了一个简单的通用解决方案。但是,这只是将每个非对象属性反序列化为String。是否可以向反序列化过程中添加一个自定义客户端回调(如上所示)?

参考方案

盒子外面:

new ObjectMapper.readValue("\"name\": ...", Map.class);

Jackson将您示例中的输入转换为:

class java.util.LinkedHashMap(
    name -> class java.lang.String(Bill), 
    age -> class java.lang.Integer(53), 
    address -> class java.util.LinkedHashMap(
        street -> class java.lang.String(Wallstreet), 
        city -> class java.lang.String(NY)
    )
)

如果要进行一些自定义处理(例如,要使用BigInteger而不是整数作为年龄),则可以使用自定义LinkedHashMap实现,例如:

public class CustomMap extends LinkedHashMap<String, Object> {
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    private Object convertPrimitive(String key, Object value) {
        switch (key) {
            case "age":
                return new BigInteger(value.toString());
            case "city":
                return value.toString().toLowerCase();
            default:
                return value;
        }
    }

    private Object convertMap(String key, Object value) {
        return OBJECT_MAPPER.convertValue(value, CustomMap.class);
    }

    @Override
    public Object put(String key, Object value) {
        return super.put(key, (value instanceof Map) ? convertMap(key, value) : convertPrimitive(key, value));
    }
}

这次,

new ObjectMapper.readValue("\"name\": ...", CustomMap.class);

将导致:

class org.example.CustomMap(
    name -> class java.lang.String(Bill), 
    age -> class java.math.BigInteger(53), 
    address -> class org.example.CustomMap(
        street -> class java.lang.String(Wallstreet), 
        city -> class java.lang.String(ny)
    )
)

SOAPFaultException部署在Tomcat上时,但在GlassFish中工作正常 - java

朋友们,我一直在尝试很多,阅读了很多论坛,但无法理解为什么出现此问题。我使用契约优先方法创建了一个Jax-WS WebService。创建WSDL和XSD,然后使用wsimport工具生成其余工件,为SEI提供实现。将WebService应用程序部署到Eclipse Helios中的GlassFish(Glassfish适配器和Eclipse中安装的插件)。…

Java Applet的URLConnection与PHP无效 - java

我已经研究了Oracle文档和示例,但仍然无法正常工作。我有一个Java Applet,它只是尝试使用URLConnection和OutputStreamWriter通过POST将文本字段发送到PHP脚本。 Java方面似乎工作正常,没有引发异常,但是PHP在我的页面上未显示任何输出。我是PHP新手,因此请耐心等待。这是相关的Java部分: try { UR…

Jackson JsonTypeInfo用于HashMap <String,Object>的内容 - java

我有一个JSON文件(无法控制),如下所示:{ "some-identifier": { "@class": "some-prefix.ClassA", "<classA-property1>": "value1", "<class…

页面加载而不是提交时发生struts验证 - java

请原谅我;我对Struts有点陌生。我遇到一个问题,即页面加载而不是我实际提交表单时发生了验证。我整天都在论坛上搜寻和搜寻,没有任何运气。我显然做错了一些事情,应该很容易确定,但是我还没有发现问题所在。这是我的struts.xml的片段:<action name="*Test" method="{1}" clas…

无法从ArrayList <String>转换为List <Comparable> - java

当我写下面的代码时,编译器说 无法从ArrayList<String>转换为List<Comparable>private List<Comparable> get(){ return new ArrayList<String>(); } 但是当我用通配符编写返回类型时,代码会编译。private List&l…