Как сериализовать и десериализовать объект JSON из геокодирования Google с помощью Java

Я работаю с ответами Google Geocode в формате JSON.

Формат JSON выглядит следующим образом:

{
  "status": "OK",
  "results": [ {
  "types": [ "street_address" ],
  "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
  "address_components": [ {
     "long_name": "1600",
     "short_name": "1600",
     "types": [ "street_number" ]
  }, {
  "long_name": "Amphitheatre Pkwy",
  "short_name": "Amphitheatre Pkwy",
  "types": [ "route" ]
}, {
  "long_name": "Mountain View",
  "short_name": "Mountain View",
  "types": [ "locality", "political" ]
}, {
  "long_name": "California",
  "short_name": "CA",
  "types": [ "administrative_area_level_1", "political" ]
}, {
  "long_name": "United States",
  "short_name": "US",
  "types": [ "country", "political" ]
}, {
  "long_name": "94043",
  "short_name": "94043",
  "types": [ "postal_code" ]
} ],
"geometry": {
  "location": {
    "lat": 37.4219720,
    "lng": -122.0841430
  },
  "location_type": "ROOFTOP",
  "viewport": {
    "southwest": {
      "lat": 37.4188244,
      "lng": -122.0872906
    },
    "northeast": {
      "lat": 37.4251196,
      "lng": -122.0809954
    }
  }
}
} ]
}

Я пытаюсь создать их сериализовать и десериализовать с помощью Java. Я пробовал GSON, но поскольку он не может десериализовать объекты на более глубоком уровне, GSON не будет вариантом.

Мне просто интересно, есть ли у кого-нибудь опыт по этой теме? Возможно, вы пробовали библиотеку, которая может решить эту проблему? Какой-нибудь пример кода был бы потрясающим.

Я действительно не хочу писать для этого свой собственный API ...


person hook38    schedule 01.09.2011    source источник
comment
GSON может полностью десериализовать произвольный JSON.   -  person Matt Ball    schedule 01.09.2011
comment
Действительно. См. Также stackoverflow.com/questions/1688099/converting-json-to- java   -  person BalusC    schedule 01.09.2011
comment
См. Также stackoverflow.com/q/2378402/45935. Джексон является еще одним сильным соперником и может сериализовать / десериализовать иерархии объектов Java. на довольно высокой скорости. У меня был хороший опыт с этим.   -  person Jim Ferrans    schedule 01.09.2011
comment
Большое тебе спасибо. В конце концов решил использовать Джексона. проблема решена: p   -  person hook38    schedule 01.09.2011
comment
GoogleGeoCodeResponse result = mapper.readValue (jsonInOneString, GoogleGeoCodeResponse.class);   -  person romu31    schedule 30.11.2012


Ответы (5)


Использование Джексона

GoogleGeoCodeResponse result = mapper.readValue(jsonInOneString,GoogleGeoCodeResponse.class);

public class GoogleGeoCodeResponse {

     public String status ;
        public results[] results ;
        public GoogleGeoCodeResponse() {

        }
    }

     class results{
        public String formatted_address ;
        public geometry geometry ;
        public String[] types;
        public address_component[] address_components;
    }

     class geometry{
         public bounds bounds;
        public String location_type ;
        public location location;
        public bounds viewport;
    }

     class bounds {

         public location northeast ;
         public location southwest ;
     }

     class location{
        public String lat ;
        public String lng ;
    }

     class address_component{
        public String long_name;
        public String short_name;
        public String[] types ;
    }
person romu31    schedule 30.11.2012
comment
ну, вы всегда можете добавить лучшее / более объясненное решение. mine: у вас есть ввод String, класс, отображающий результат, и вы используете Jackson для десериализации ввода в класс. - person romu31; 27.01.2015

если у кого-то есть такой же вопрос, вы можете использовать GoogleGeoCodeResponse, предоставленный romu31:

public class GoogleGeoCodeResponse {
public String status;
public results[] results;

public GoogleGeoCodeResponse() {
}

public class results {
    public String formatted_address;
    public geometry geometry;
    public String[] types;
    public address_component[] address_components;
}

public class geometry {
    public bounds bounds;
    public String location_type;
    public location location;
    public bounds viewport;
}

public class bounds {

    public location northeast;
    public location southwest;
}

public class location {
    public String lat;
    public String lng;
}

public class address_component {
    public String long_name;
    public String short_name;
    public String[] types;
}}

и Gson API Пример:

 Gson gson = new Gson();
 GoogleGeoCodeResponse result = gson.fromJson(jsonCoord(URLEncoder.encode(address, "UTF-8"));

            GoogleGeoCodeResponse.class);

    double lat = Double.parseDouble(result.results[0].geometry.location.lat);

    double lng = Double.parseDouble(result.results[0].geometry.location.lng);

и эта функция, чтобы получить это:

private String jsonCoord(String address) throws IOException {
URL url = new URL("http://maps.googleapis.com/maps/api/geocode/json?address=" + address + "&sensor=false");
URLConnection connection = url.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String inputLine;
String jsonResult = "";
while ((inputLine = in.readLine()) != null) {
    jsonResult += inputLine;
}
in.close();
return jsonResult; 
}
person Smile2Life    schedule 29.01.2013

Вы всегда можете использовать http://www.jsonschema2pojo.org/. Что делает это за вас, и вам не нужно делать это вручную.


person РАВИ    schedule 04.04.2014

Хотя вопрос касается сериализации и десериализации JSON, неясно, какова ваша настоящая цель. Возможно, вы просто хотите иметь возможность использовать информацию о геолокации в коде Java, и в этом случае я бы предположил, что почти все API информации о геолокации имеют Java SDK / клиенты. Вот ссылка на Google и в SmartyStreets, это две службы, с которыми я знаком.

Вот пример, скопированный прямо из репозитория Google. Как видите, это упрощает доступ к данным.

GeoApiContext context = new GeoApiContext().setApiKey("AIza...");
GeocodingResult[] results =  GeocodingApi.geocode(context,
    "1600 Amphitheatre Parkway Mountain View, CA 94043").await();
System.out.println(results[0].formattedAddress);

(Полное раскрытие: я работал на SmartyStreets.)

person Joe    schedule 30.09.2016

Джексон лучший, я использовал класс модели, предоставленный romu31, поместил библиотеку Джексона в путь к классам и использовал Spring RestTemplate, чтобы напрямую получить GeocodeResponse.

    public class GeocodeResponse {

    public String status;
    public results[] results;

    public GeocodeResponse() {
    enter code here
    }
}

class results {
    public String formatted_address;
    public geometry geometry;
    public String[] types;
    public address_component[] address_components;
}

class geometry {
    public bounds bounds;
    public String location_type;
    public location location;
    public bounds viewport;
}

class bounds {

    public location northeast;
    public location southwest;
}

class location {
    public String lat;
    public String lng;
}

class address_component {
    public String long_name;
    public String short_name;
    public String[] types;
}

Обратите внимание, что я помещаю только библиотеку Джексона в путь к классам, мне даже не нужно выполнять какой-либо метод API от Джексона, пожалуйста, см. Мои тестовые коды ниже

RestTemplate restTemplate = new RestTemplate();
        Map<String, String> vars = new HashMap<String, String>();

        vars.put("address", "Hong Kong");
        vars.put("sensor", "false");

        GeocodeResponse result = restTemplate.getForObject(
                "http://maps.googleapis.com/maps/api/geocode/json?address={address}&sensor={sensor}",
                GeocodeResponse.class, vars);

Однако в этом решении есть небольшая проблема: имена классов и имена свойств недостаточно хороши. Это как-то в плохой условности. Я знаю, что мы можем преобразовать имя класса и имена свойств в лучшее соглашение, но это потребует определенных усилий для реализации логики маршалла данных.

person user3659103    schedule 25.08.2016