1

One of our servers has an API endpoint that sometimes returns MAC addresses in a list (up to 3) and sometimes it returns a single MAC address

Can be this:

{
    "mac_addrs": [
        "11:11:11:11:11:11",
        "22:22:22:22:22:22"
    ]
}

Or just:

{
    "mac_addr": "33:33:33:33:33:33"
}

Now, in the Java side I have a little PoJo (class MacAddress) that takes a String in the constructor, transforms it to binary and provides some nice to have methods, such as verifiers, manufacturer extractors... things like that.

I have created a Jacskson custom deserializer to, given a String containing a MAC address, converter it to an actual instance of that MacAddress class:

@Override
public MacAddress deserialize(JsonParser jp, DeserializationContext ctxt) 
       throws IOException {
    JsonToken currentToken = jp.getCurrentToken();
    if (currentToken.equals(JsonToken.VALUE_STRING)) {
        return new MacAddress(jp.getValueAsString());
    }
    return null;
}

That can be used as an annotation in the class loaded from the RESTful API (from the JSON):

@JsonIgnoreProperties(ignoreUnknown = true)
public class Device {
    @JsonDeserialize(using = MacAddressDeserializer.class)
    @JsonSerialize(using = MacAddressSerializer.class)
    public MacAddress mac;
    // . . . moar and moar thingies

Now, the question:

Is there a way to tell Jackson (version 2.5.1, but I could increase it, if it'd help) to model a class with a List<MacAddress> and use the same deserializer for a single one? Basically, being able to tell Jackson something along the lines of "I'm not lying to you: you're gonna be receiving a list of MAC addresses, so for each item in the list, I'd like you to use the MacAddressDeserializer.class that I have already defined somewhere"

I have found lots of examples, but all of them explaining how to implement a deserializer for a list of objects, or for a single object, or for forcing a list even if there's only one object, but I'd like having to avoid writing two deserializers, one for MacAddress and a second one for List<MacAddress>. Is there a way of using the same deserializer class for both things?

Thank you in advance.

Community
  • 1
  • 1
Savir
  • 17,568
  • 15
  • 82
  • 136
  • Why don't you register `MacAddressDeserializer` on `ObjectMapper` directly without annotations? I think this will give you expected result. – varren May 16 '16 at 17:06
  • Oh! Thank you for the reply... well.. the answer was _"because I don't know how to do that"_, but you gave me a great hint. I'm gonna start digging! :) Thank you @varren – Savir May 16 '16 at 17:08
  • 1
    http://wiki.fasterxml.com/JacksonHowToCustomDeserializers here is docs and btw i think you don't need custom deserializer if you just want to map string to your POJO. single-String constructor/factory method should be enough – varren May 16 '16 at 17:10
  • 1
    and one more tip... if you want to serialize you POJO back to string you could use `@JsonValue` on `MacAddress` String getter. – varren May 16 '16 at 17:22
  • Appreciate all the hints! The biggest problem (due to my lack of knowledge) is that I'm using Jackson in conjunction with Google APIs, and I can't see clearly _where_ to register the custom serializer. But you gave me a lot of tips already! I'll try and research a bit :) Thank you again :+1: – Savir May 16 '16 at 17:33

0 Answers0