0

I'm trying to deserialize a Json object that contains the following structure but am getting an error from Jackson during deserialization due to null values appearing in the the map containing the Json object. Is there a way to deserialize these values and put them in the map as either null or an empty string?

{
    "id": "1"
    "links: {
          "a": "someLink"
          "b": null
          ....
     }
}

I have created an immutable in the following way:

@Value.Immutable
@JsonSerialize(as = ImmutableMyClass.class)
@JsonDeserialize(as = ImmutableMyClass.class)
public interface MyClass {

    @JsonProperty("id")
    String getId();

    @JsonProperty("links")
    Map<String, String> getLinks();
}

I'm reading the object into the Java POJO like this:

List<MyClass> myClassList = objectMapper.readValue(jsonString, objectMapper.getTypeFactory.constructCollectionType(List.class, ImmutableMyClass.class))

Error:

com.fasterxml.jackson.databind.exc.ValueInstantiationException problem: null value in entry: b=null
prestigem
  • 47
  • 7

2 Answers2

0

Maybe try something like this (to use @Value.Immutable over interface)

@JsonProperty("links")
Map<String, Optional<String>> getLinks();

@Value.Lazy
Map<String, String> getLinksValues() {
    return getLinks().entrySet().collect(Map.Entry::getKey, e -> e.getValue().orElse(null)));
}

or (without @Value.Immutable)

private final Map<String, String> links;

setLinks(Map<String, String> links) {
    this.links = links;
}

Map<String, String> getLinks() {
    return links;
}
y07k2
  • 1,898
  • 4
  • 20
  • 36
0

I just tried your testcase with Jackson version 2.15.2 and it worked just fine. I didn't use Immutable annotation and also didn't use @JsonSerialize and @JsonDeserialize annotations. Here is my code and output I got:

class MapHolder:

package com.mgnt.stam;

import java.util.Map;

public class MapHolder {
    private Integer id;
    private Map<String, Object> address;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Map<String, Object> getAddress() {
        return address;
    }

    public void setAddress(Map<String, Object> address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "MapHolder{" +
                "id=" + id +
                ", address=" + address +
                '}';
    }

}

My code:

try{        
        MapHolder mapHolder = JsonUtils.readObjectFromJsonString("{\"id\": 1,\"address\": {\"city\": \"Mountain View\",\"state\": \"CA\",\"zipcode\": 94041, \"appt\": null}}", MapHolder.class);
        System.out.println(mapHolder);
    } catch (IOException e) {
        ...;
    }

The output:

MapHolder{id=1, address={city=Mountain View, state=CA, zipcode=94041, appt=null}}

Clarification: class JsonUtils comes from MgntUtils Open Source library written and maintained by me. This class is a thin wrapper over ObjectMapper class from Jackson v 2.15.2. Here is a Javadoc for JsonUtils. The library could be obtained as a Maven artifact from Maven Central or from GitHub (including source code and Javadoc)

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36