복붙노트

[SPRING] JSON을 읽을 수 없습니다. START_OBJECT 토큰 중 hello.Country []의 인스턴스를 deserialize 할 수 없습니다.

SPRING

JSON을 읽을 수 없습니다. START_OBJECT 토큰 중 hello.Country []의 인스턴스를 deserialize 할 수 없습니다.

나는 나에게 모든 나라를 제공하는 나머지 URL을 가지고있다 - http://api.geonames.org/countryInfoJSON?username=volodiaL.

Spring 객체의 RestTemplate을 사용하여 반환 된 json을 java 객체로 파싱합니다.

RestTemplate restTemplate = new RestTemplate();
Country[] countries = restTemplate.getForObject("http://api.geonames.org/countryInfoJSON?username=volodiaL",Country[].class);

이 코드를 실행하면 예외가 발생합니다.

Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of hello.Country[] out of START_OBJECT token
 at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@1846149; line: 1, column: 1]
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:691)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:685)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.handleNonArray(ObjectArrayDeserializer.java:222)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:133)
    at com.fasterxml.jackson.databind.deser.std.ObjectArrayDeserializer.deserialize(ObjectArrayDeserializer.java:18)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2993)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2158)
    at org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.readJavaType(MappingJackson2HttpMessageConverter.java:225)
    ... 7 more

마지막으로 내 Country 클래스 :

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class Country {
    private String countryName;
    private long geonameId;

    public String getCountryName() {
        return countryName;
    }

    public long getGeonameId() {
        return geonameId;
    }

    @Override
    public String toString() {
        return countryName;
    }
}

문제는 반환 된 json에는 다음과 같은 국가 요소 배열을 포함하는 루트 요소 "geonames"가 포함되어 있다는 것입니다.

{
"geonames": [
    {
        "continent": "EU",
        "capital": "Andorra la Vella",
        "languages": "ca",
        "geonameId": 3041565,
        "south": 42.42849259876837,
        "isoAlpha3": "AND",
        "north": 42.65604389629997,
        "fipsCode": "AN",
        "population": "84000",
        "east": 1.7865427778319827,
        "isoNumeric": "020",
        "areaInSqKm": "468.0",
        "countryCode": "AD",
        "west": 1.4071867141112762,
        "countryName": "Andorra",
        "continentName": "Europe",
        "currencyCode": "EUR"
    }
]
}

배열의 각 요소를 Country 객체로 변환하도록 RestTemplate에 알려주는 방법은 무엇입니까?

해결법

  1. ==============================

    1.다음을 수행해야합니다.

    다음을 수행해야합니다.

    public class CountryInfoResponse {
    
       @JsonProperty("geonames")
       private List<Country> countries; 
    
       //getter - setter
    }
    
    RestTemplate restTemplate = new RestTemplate();
    List<Country> countries = restTemplate.getForObject("http://api.geonames.org/countryInfoJSON?username=volodiaL",CountryInfoResponse.class).getCountries();
    

    어떤 종류의 주석을 사용하여 레벨을 건너 뛸 수 있다면 좋지만 아직 불가능합니다 (이것을 참조하십시오)

  2. ==============================

    2.다른 해결책 :

    다른 해결책 :

    public class CountryInfoResponse {
      private List<Object> geonames;
    }
    

    부울과 같은 다른 Datatype이 있었기 때문에 일반적인 Object-List를 사용하여 내 문제를 해결했습니다.

  3. ==============================

    3.필자의 경우, JQuery를 사용하여 값을 얻었고 다음과 같이했다.

    필자의 경우, JQuery를 사용하여 값을 얻었고 다음과 같이했다.

    var newUserInfo = { "lastName": inputLastName[0].value, "userName": inputUsername[0].value,
     "firstName": inputFirstName[0] , "email": inputEmail[0].value}
    

    그리고 나는 끊임없이이 예외를 얻고 있었다.

    그리고이 "firstName"다음에 .value를 쓰는 것을 잊어 버릴 때까지 한 시간 씩 머리를 숙였습니다 : inputFirstName [0].

    올바른 솔루션은 다음과 같습니다.

    var newUserInfo = { "lastName": inputLastName[0].value, "userName": inputUsername[0].value,
     "firstName": inputFirstName[0].value , "email": inputEmail[0].value}
    

    나는이 문제가 있었기 때문에 여기에 왔고 나는 다른 사람을 몇 시간이나 구원하기를 희망한다.

    건배 :)

  4. ==============================

    4.추가 Class 및 List 게놈을 사용하지 않으려면 맵을 사용하면됩니다.

    추가 Class 및 List 게놈을 사용하지 않으려면 맵을 사용하면됩니다.

    데이터 구조는 Map >로 변환됩니다.

    String resourceEndpoint = "http://api.geonames.org/countryInfoJSON?username=volodiaL";
    
    Map<String, List<Country>> geonames = restTemplate.getForObject(resourceEndpoint, Map.class);
    
    List<Country> countries = geonames.get("geonames");
    
  5. ==============================

    5.Spring 부트 1.3.3의 경우 list에 대한 메소드 exchange ()가 작동합니다. 관련 답변에서와 같이

    Spring 부트 1.3.3의 경우 list에 대한 메소드 exchange ()가 작동합니다. 관련 답변에서와 같이

    봄 데이터 나머지 - _links

  6. from https://stackoverflow.com/questions/24864489/could-not-read-json-can-not-deserialize-instance-of-hello-country-out-of-star by cc-by-sa and MIT license