1. ホーム
  2. java

[解決済み] String値からデシリアライズするためのString引数のコンストラクタ/ファクトリメソッドがない('')。

2022-02-04 14:10:59

質問

を使用する際に、jsonのパースに関する問題が発生しました。 ObjectMapper クラスから com.fasterxml.jackson.databind というパッケージで、出てくるエラーは

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

この問題が発生しているウェブアプリケーションは、AngularJSフロントエンドを使用したSpring MVCアプリケーションですが、もっと小さな、すべてのJavaプログラムでこの問題を再現することができます。以下は私のビーンです。

出荷.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;
    }
}

アクティビティ.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;
    }
}

アクティビティロケーション.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;
    }
}

アドレス.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;
    }
}

以下は、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();
    }
}

のデータを調整する場合 jsonMessage というエラーが発生します。

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

で、ここからjsonを変更すると問題が発生します。

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

をこれに変更します。

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

の値を送信する代わりに Address ビーンでは、空の文字列が表示されるだけです。残念ながら、私は第三者からデータを受け取っており、受け取るデータを制御することはできません。

これを処理できるようにするために追加する必要があるアノテーションはありますか?

どのように解決するのですか?

設定方法

mapper.configure(
          DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,
          true)

または

mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

は、お使いのJacksonのバージョンに依存します。