简体   繁体   中英

Jackson Custom Number Parsing

I want to have Jackson always parse numbers as Long or Double.

I have a class like the following with the corresponding getters and setters:

public class Foo {
    private HashMap<String, ArrayList<HashMap<String, Object>>> tables;

    ...

}

And some Json that looks like so:

{ "tables" : 
    { "table1" : 
        [
            { "t1Field1" : 0,
              "t1Field2" : "val2" 
            },
            { "t1Field1" : 1,
              "t1Field2" : "val4" 
            }
        ]
    }
}

Jackson will parse the values for t1Field1 as Integers/Longs and Floats/Doubles based on the size of the number. But I want to always get Longs and Doubles.

I'm almost certain I have to write a custom deserializer or parser to do this and I have looked through examples but haven't found anything that works how I would imagine. I just want to extend existing Jackson functionality and override what happens for numbers. I don't want to write a whole deserializer for Objects. I just want to do something like:

public class CustomerNumberDeserializer extends SomethingFromCoreJackson {
    public Object deserialize() {
        Object num;
        num = super.deserialize();
        if (num instanceof Integer)
            return Long.valueOf(((Integer)num).intValue());
        return num;
    }
}

But all the Jackson classes that I thought to extend were either final or abstract and seemed to require a bunch of extra work. Is what I want possible?

After revisiting this I found the class that I wanted to extend. Hope this helps someone.

I created a custom deserializer as follows:

/**
 * Custom deserializer for untyped objects that ensures integers are returned as longs
 */
public class ObjectDeserializer extends UntypedObjectDeserializer {

    private static final long serialVersionUID = 7764405880012867708L;

    @Override
    public Object deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException {

        Object out = super.deserialize(jp, ctxt);
        if (out instanceof Integer) {
            return Long.valueOf((Integer)out).longValue();
        }
        return out;
    }

    @Override
    public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt,
            TypeDeserializer typeDeserializer) throws IOException {

        Object out = super.deserializeWithType(jp, ctxt, typeDeserializer);
        if (out instanceof Integer) {
            return Long.valueOf((Integer)out).longValue();
        }
        return out;
    }
}

And configured my object mapper to use it:

ObjectMapper om = new ObjectMapper();
SimpleModule mod = new SimpleModule().addDeserializer(Object.class, new ObjectDeserializer());
om.registerModule(mod);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM