简体   繁体   中英

Jackson com.fasterxml.jackson.databind.exc.MismatchedInputException with empty string

Having following json fragment:

"Location": {
    "Address": ""
},

And my Pojo

public class Address implements Serializable
{

    @JsonProperty("City")
    private String city;
    @JsonProperty("StateProvinceCode")
    private String stateProvinceCode;
    @JsonProperty("PostalCode")
    private String postalCode;
    @JsonProperty("CountryCode")
    private String countryCode;
    private final static long serialVersionUID = -4475717488164417476L;

    /**
     * No args constructor for use in serialization
     * 
     */
    public Address() {
    }

    /**
     * 
     * @param city
     * @param countryCode
     * @param postalCode
     * @param stateProvinceCode
     */
    public Address(String city, String stateProvinceCode, String postalCode, String countryCode) {
        super();
        this.city = city;
        this.stateProvinceCode = stateProvinceCode;
        this.postalCode = postalCode;
        this.countryCode = countryCode;
    }

getters and settes ...

I got com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.xxx.Address (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('')\\n at [Source: UNKNOWN; line: -1, column: -1]

Which seems pretty obvious, empty string cannot be deserialized as Address. The issue here is sometimes response comes as empty string and others as complete Address Objec.

How can I configure Jackson objectMapper to tell to ignore if empty string is present??

This response is from an external source, so I cannot modify that response.

Here is my Object Mapper configuration

@Bean
  public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new Jdk8Module());
    mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    return mapper;
  }

Additional note: Pojo classes are generated using jsonschema2pojo gradle plugin and are based on json schemas

As suggested by @Dmitry Zagorulkin, turn DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT to true . For more details, check docs .

Here is the code I tried to replicate the issue and fixed by adding the line highlighted by comment.

public class JacksonExample2 {

    private static String json1 = "{\r\n" + 
         "  \"Location\": {\r\n" + 
         "    \"Address\": \"\"\r\n" + 
         "  }\r\n" + 
         "}";


    public static void main(String[] args) throws JSONException, IOException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new Jdk8Module());
        mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
        // Add this line
        mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
        ParentData parentData = mapper.readValue(json1, ParentData.class);
        Address address = new Address("New York", null, null, null);
        LocationData locationData = new LocationData(address);
        System.out.println(parentData);
    }

}

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
class ParentData {
    @JsonProperty("Location")
    private LocationData locationData;
}

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
class LocationData {
    @JsonProperty("Address")
    private Address address;
}

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
class Address implements Serializable {

    @JsonProperty("City")
    private String city;
    @JsonProperty("StateProvinceCode")
    private String stateProvinceCode;
    @JsonProperty("PostalCode")
    private String postalCode;
    @JsonProperty("CountryCode")
    private String countryCode;
    private final static long serialVersionUID = -4475717488164417476L;
}

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