4

我正在使用 JSON 格式的 Google Geocode 响应。

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...

4

5 回答 5

16

使用杰克逊

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 ;
    }
于 2012-11-30T02:29:55.970 回答
2

您始终可以使用http://www.jsonschema2pojo.org/。哪个为你做,你不必手动做。


于 2014-04-04T04:46:47.843 回答
2

如果有人有同样的问题,您可以使用 romu31 提供的 GoogleGeoCodeResponse :

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; 
}
于 2013-01-29T17:42:42.570 回答
2

尽管问题询问 JSON 序列化和反序列化,但尚不清楚您的真正目标是什么。可能您只是希望能够在 Java 代码中使用地理位置信息,在这种情况下,我建议几乎所有地理位置信息 API 都具有 Java SDK/客户端。这是GoogleSmartyStreets 的链接,这是我熟悉的两项服务。

这是直接从 Google 的 repo 复制和粘贴的示例。如您所见,它使访问数据变得非常容易。

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 工作过。)

于 2016-09-30T16:24:05.797 回答
0

Jackson是最好的,我利用了romu31提供的模型类,将jackson库放在类路径中,使用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);

但是,这个解决方案有一个小问题,类名和属性名不够好。不知何故,它的惯例很糟糕。我知道我们可以将类名和属性名重构为更好的约定,但这意味着实现数据编组逻辑需要付出一定的努力。

于 2016-08-25T07:00:13.880 回答