开发者

How to serialize and deserialize a JSON object from Google geocode using Java

开发者 https://www.devze.com 2023-04-01 20:39 出处:网络
I am working with Google Geocode responses, which are in JSON. The JSON format is as follows: { \"status\": \"OK\",

I am working with Google Geocode responses, which are in JSON.

The JSON format is as follows:

{
  "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
    }
  }
}
} ]
}

I am trying to create serialize and deserialize them using Java. I tried GSON, but because it cannot deserialize objects in a deeper level, GSON will not be an option.

I'm just wondering if anyone has experience on this topic? Perhaps you have tried a library that can solve this problem? Some sample code would be awesome.

I really don't want to write my own API for this...


Using Jackson

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 ;
    }


if someone have same question you can use GoogleGeoCodeResponse provided by 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;
}}

and Gson API Ex:

 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);

and this function to get it:

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; 
}


You can always use http://www.jsonschema2pojo.org/. Which does it for you, and you don't have to manually do it.



Though the question asks about JSON serialization and deserialization, it's not clear what your real goal is. It could be that you just want to be able to use the geolocation information in Java code, and in that case I would suggest that almost all geolocation information APIs have Java SDKs/clients. Here is the link to Google's and to SmartyStreets's, which are two services I'm familiar with.

Here is an example copy-and-pasted straight from Google's repo. As you can see, it makes it very easy to access the data.

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);

(Full disclosure: I have worked for SmartyStreets.)


Jackson is the best, I made use of the model class provided by romu31, put the jackson library in class path and use the Spring RestTemplate to get the GeocodeResponse directly.

    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;
}

Please note I only put the jackson library in classpath, I don't even need to execute any API method from jackson, please see my test codes below

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);

However, there is a minor issue on this solution, the class names and property names are not nice enough. It's somehow in bad convention. I know that we can refactor the class name and property names into better convention, but it would imply certain effort to implement the data marhsall logic.

0

精彩评论

暂无评论...
验证码 换一张
取 消