Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No String-argument constructor/factory method to deserialize from String value ('')

Tags:

java

json

spring

I'm running into a json parsing issue when using the ObjectMapper class from the com.fasterxml.jackson.databind package, and the error that I'm getting is:

com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of com.graybar.utilities.ups.beans.Address: no String-argument constructor/factory method to deserialize from String value ('') 

The web application where this problem is occurring is a Spring MVC application using an AngularJS front end, but I can duplicate the issue with a much smaller, all java program. Here are my beans:

Shipment.java

@JsonIgnoreProperties(ignoreUnknown = true) public class Shipment {     @JsonProperty("Activity")     private ArrayList<Activity> activity;     public ArrayList<Activity> getActivity() {         return activity;     }     public void setActivity(ArrayList<Activity> activity) {         this.activity = activity;     } } 

Activity.java

@JsonIgnoreProperties(ignoreUnknown = true) public class Activity {     @JsonProperty("ActivityLocation")     private ArrayList<ActivityLocation> activityLocation;     public ArrayList<ActivityLocation> getActivityLocation() {         return activityLocation;     }     public void setActivityLocation(ArrayList<ActivityLocation> activityLocation) {         this.activityLocation = activityLocation;     } } 

ActivityLocation.java

@JsonIgnoreProperties(ignoreUnknown = true) public class ActivityLocation {     @JsonProperty("Address")     private Address address;     public Address getAddress() {         return address;     }     public void setAddress(Address address) {         this.address = address;     } } 

Address.java

@JsonIgnoreProperties(ignoreUnknown = true) public class Address {     @JsonProperty("City")     private String city;     @JsonProperty("StateProvinceCode")     private String stateProvinceCode;     @JsonProperty("CountryCode")     private String countryCode;     public String getCity() {         return city;     }     public void setCity(String city) {         this.city = city;     }     public String getCountryCode() {         return countryCode;     }     public void setCountryCode(String countryCode) {         this.countryCode = countryCode;     }     public String getStateProvinceCode() {         return stateProvinceCode;     }     public void setStateProvinceCode(String stateProvinceCode) {         this.stateProvinceCode = stateProvinceCode;     } } 

Here is the code where I can properly map the json:

public static void main(String[] args) {     String jsonMessage = "" +         "{" +          "   \"Activity\": [{ " +         "       \"ActivityLocation\": { " +         "           \"Address\": { " +         "               \"City\": \"Hana\", " +         "               \"StateProvinceCode\": \"Hi\", " +         "               \"CountryCode\": \"US\" " +         "           } " +         "       } " +         "   }, " +         "   { " +         "       \"ActivityLocation\": { " +         "           \"Address\": { " +         "               \"City\": \"Honolulu\", " +         "               \"StateProvinceCode\": \"Hi\", " +         "               \"CountryCode\": \"US\" " +         "           } " +         "       } " +         "   }] " +     "} ";      try {         ObjectMapper mapper = new ObjectMapper();         mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);          Shipment shipment = mapper.readValue(jsonMessage, Shipment.class);         System.out.println("shipment.toString = " + shipment.toString());     } catch (Exception e) {         e.printStackTrace();     } } 

When adjusting the data in the jsonMessage var is when I run into the error that I mentioned above:

    "{" +      "   \"Activity\": [{ " +     "       \"ActivityLocation\": { " +     "           \"Address\": { " +     "               \"City\": \"Hana\", " +     "               \"StateProvinceCode\": \"Hi\", " +     "               \"CountryCode\": \"US\" " +     "           } " +     "       } " +     "   }, " +     "   { " +     "       \"ActivityLocation\": { " +     "           \"Address\": \"\" " +     "           } " +     "       } " +     "   }] " +     "} "; 

So, the problem happens when changing the json from this:

{     "ActivityLocation": {          "Address": {             "City": "Honolulu",              "StateProvinceCode": "Hi",              "CountryCode": "US"         }     } }] 

to this:

{ "ActivityLocation": {      "Address": ""     } } 

Instead of sending values for my Address bean, I'm getting just an empty string. Unfortunately, I'm receiving my data from a third party and have no control over the data I receive.

Is there an annotation that needs to be added to be able to handle this?

like image 486
Stephen Avatar asked Jul 14 '17 19:07

Stephen


1 Answers

Had this when I accidentally was calling

mapper.convertValue(...) 

instead of

mapper.readValue(...) 

So, just make sure you call correct method, since argument are same and IDE can find many things

like image 54
Andrii Plotnikov Avatar answered Sep 22 '22 14:09

Andrii Plotnikov