web-dev-qa-db-fra.com

Aucun constructeur / méthode d'usine d'argument de chaîne à désérialiser de la valeur de chaîne ('')

Je rencontre un problème d'analyse json lorsque j'utilise la classe ObjectMapper de com.fasterxml.jackson.databind package, et l'erreur que j'obtiens est:

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 ('')

L'application Web où ce problème se produit est une application Spring MVC utilisant un frontal AngularJS, mais je peux dupliquer le problème avec un programme beaucoup plus petit, tous Java. Voici mes 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;
    }
}

Voici le code où je peux correctement mapper le 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();
    }
}

Lors du réglage des données dans le jsonMessage var, c'est lorsque je rencontre l'erreur que j'ai mentionnée ci-dessus:

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

Ainsi, le problème se produit lors du changement de json à partir de ceci:

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

pour ça:

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

Au lieu d'envoyer des valeurs pour mon bean Address, je reçois juste une chaîne vide. Malheureusement, je reçois mes données d'un tiers et je n'ai aucun contrôle sur les données que je reçois.

Y a-t-il une annotation qui doit être ajoutée pour pouvoir gérer cela?

43
Stephen

Essayez de définir mapper.configure(DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)

ou

mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

en fonction de votre version Jackson.

35
Abhijit Sarkar

J'ai eu ça quand j'ai accidentellement appelé

mapper.convertValue(...)

au lieu de

mapper.readValue(...)

Donc, assurez-vous d'appeler la bonne méthode, car les arguments sont les mêmes et IDE peut trouver beaucoup de choses

27
Andrii Plotnikov

Cette exception indique que vous essayez de désérialiser l'objet "Adresse" de la chaîne "\"\"" au lieu d'une description d'objet comme "{…}". Le désérialiseur ne peut pas trouver un constructeur d'adresse avec l'argument chaîne. Vous devez remplacer "" par {} pour éviter cette erreur.

0
papaRomik