すべての国を提供する残りのURLがあります- http://api.geonames.org/countryInfoJSON?username=volodiaL 。
Spring 3の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
最後に私の国クラス:
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"
}
]
}
配列の各要素をRestTemplate
オブジェクトに変換するようにCountry
に伝える方法は?
以下を行う必要があります。
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();
何らかの種類の注釈を使用してレベルをスキップできるようにすることはできますが、まだ可能ではありません( this および this を参照)
別の解決策:
public class CountryInfoResponse {
private List<Object> geonames;
}
ジェネリックObject-Listを使用すると、ブールのような他のデータ型もあるため、私の問題を解決しました。
私の場合、JQueryで<input type="text">
の値を取得していましたが、次のようにしました。
var newUserInfo = { "lastName": inputLastName[0].value, "userName": inputUsername[0].value,
"firstName": inputFirstName[0] , "email": inputEmail[0].value}
そして、私は常にこの例外を取得していました
com.fasterxml.jackson.databind.JsonMappingException:[Source:Java.io.PushbackInputStream@39cb6c98;のSTART_OBJECTトークンからJava.lang.Stringのインスタンスをデシリアライズできません。行:1、列:54](参照チェーン:com.springboot.domain.User ["firstName"]を使用)。
そして、_.value
の後に"firstName": inputFirstName[0]
を書くのを忘れたことに気づくまで、1時間ほど頭を叩きました。
したがって、正しい解決策は次のとおりです。
var newUserInfo = { "lastName": inputLastName[0].value, "userName": inputUsername[0].value,
"firstName": inputFirstName[0].value , "email": inputEmail[0].value}
私はこの問題を抱えていたので、ここに来ました。他の誰かに何時間もの悲惨さを救うことを願っています。
乾杯:)
余分なClass
とList<Object> genomes
の使用を避けたい場合は、単にMap
を使用できます。
データ構造はMap<String, List<Country>>
に変換されます
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");