Java Geo location project

This project is based on Google Geo API. (https://developers.google.com/maps/documentation/geocoding/)java

Sample Request URl is like :web

http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=false

Resonse format is JSON.spring

{
   "results" : [
      {
         "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" : "Santa Clara",
               "short_name" : "Santa Clara",
               "types" : [ "administrative_area_level_2", "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" ]
            }
         ],
         "formatted_address" : "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
         "geometry" : {
            "location" : {
               "lat" : 37.42291810,
               "lng" : -122.08542120
            },
            "location_type" : "ROOFTOP",
            "viewport" : {
               "northeast" : {
                  "lat" : 37.42426708029149,
                  "lng" : -122.0840722197085
               },
               "southwest" : {
                  "lat" : 37.42156911970850,
                  "lng" : -122.0867701802915
               }
            }
         },
         "types" : [ "street_address" ]
      }
   ],
   "status" : "OK"
}

 

To parse the JSON objects to Java Objects,  I use Gson. maven dependency is like:json

<dependency>
     <groupId>com.googlecode.json-simple</groupId>
     <artifactId>json-simple</artifactId>
     <version>1.1.1</version>
</dependency>
<dependency>
     <groupId>com.google.code.gson</groupId>
     <artifactId>gson</artifactId>
     <version>1.7.1</version>
</dependency>

 

To call Google API, I need to create a HTTP client.api

public String handleRequest(){
        HttpClient client = new HttpClient();
        GetMethod method = new GetMethod(url);
        method.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
                new DefaultHttpMethodRetryHandler(3, false));

        String containerStr="";
        try {
            int statusCode = client.executeMethod(method);
            if (statusCode != HttpStatus.SC_OK) {
                System.err.println("Method failed: " + method.getStatusLine());
            }
            byte[] responseBody = method.getResponseBody();
            containerStr = generateJsonResults(new String(responseBody));
            
        } catch (HttpException e) {
            System.err.println("Fatal protocol violation: " + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            System.err.println("Fatal transport error: " + e.getMessage());
            e.printStackTrace();
        } finally {
            method.releaseConnection();
        }
        
        return containerStr;
    }

 

GenrateJson Results method is the core of parsing Google Json response. becauese many of the initial responses are not needed. i only care about the request status, city, country and full address.spring-mvc

Here is GenrateJson Methodsession

public String generateJsonResults(String jsonStr){
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES);
        gsonBuilder.registerTypeAdapter(Child[].class, new ChildrenDeserializer());
        gsonBuilder.registerTypeAdapter(ChildContainer[].class, new ChildContainerDeserializer());
        Gson gson = gsonBuilder.create();
        Container container1 = gson.fromJson(jsonStr, Container.class);
        String processedResult = gson.toJson(container1);
        //System.out.println(processedResult);
        
        //change response structure
        //Collection collection = new ArrayList();
        Container responseContainer = new Container();
        responseContainer.setStatus(container1.getStatus());
        
        //collection.add(container1.getStatus());
        ChildContainer[] childContainer =container1.getResults();
        ArrayList<PopulateAddress> collectionofAddresses = new ArrayList<PopulateAddress>();
        String full_address="";
        String city="";
        String country="";
        String postal_code="";
        for(int i = 0 ; i< childContainer.length; i++){
            Child[] addressComponents = childContainer[i].getAddress_components();
            full_address = childContainer[i].getFormatted_address();
            for(int j = 0 ; j< addressComponents.length; j++){
                if(addressComponents[j].getTypes()[0].equals("administrative_area_level_1")){
                    city = addressComponents[j].getLong_name();
                }else if(addressComponents[j].getTypes()[0].equals("country")){
                    country = addressComponents[j].getLong_name();
                }else if(addressComponents[j].getTypes()[0].equals("postal_code")){
                    postal_code = addressComponents[j].getLong_name();
                }
            }
            PopulateAddress pairs = new PopulateAddress(full_address,city,country,postal_code);
            collectionofAddresses.add(pairs);

        }
        responseContainer.setReponses(collectionofAddresses);
        String json = gson.toJson(responseContainer);
        System.out.println(json);
        return json;
    }

To use GsonBuilder, i need to create two deserializer (https://sites.google.com/site/gson/gson-user-guide). ChildrenDeserializer and ChildContainerDeserializer. the source code for this is in the attachement. Basically, it looks like:mvc

import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;


public class ChildContainerDeserializer implements JsonDeserializer<ChildContainer[]> {

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.google.gson.JsonDeserializer#deserialize(com.google.gson.JsonElement,
     * java.lang.reflect.Type, com.google.gson.JsonDeserializationContext)
     */
    public ChildContainer[] deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {
        if (json instanceof JsonArray) {
            return new Gson().fromJson(json, ChildContainer[].class);
        }
        ChildContainer childContainer = context.deserialize(json, ChildContainer.class);
        return new ChildContainer[] { childContainer };
    }
}

 

To parse the Full Google Json responses, i need to convert each part of the json objects to POJOs. For example, the Container POJO contains three elements status, results, and responses(used to generate output JSON). And results are actually an array of ChildContainer. ChildContainer actually models the structure of the results, e.g. an array of Child, formatted_address. Child POJO models the data structure in address_components. Child POJO contains long_name, and String[] types.app

After all these work, i can convert the Google Json response to the format as below:jsp

{"status":"OK","responses":[{"full_address":"XXX","city":"XXXXX","country":"XXXXXX","postal_code":"XXXX"},{"full_address":"XXX","city":"XXXXX","country":"XXXX","postal_code":"XXXX"}]}

 

The final step is to put all these into web service using Spring Serverlet Dispatcher.

Web XML is like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="GeoLocationWebApp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>GeoLocationWebApp</display-name>
  
      <servlet>
        <servlet-name>springMVCServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>springMVCServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <session-config>
        <session-timeout>40</session-timeout>
    </session-config>    
</web-app>

Servlet-context.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.sample.geolocate.json" />

    <mvc:annotation-driven />

</beans>
@Controller
public class JsonService {

  @RequestMapping(value="{name}", method = RequestMethod.GET)
  public @ResponseBody String getPerson(@PathVariable String name){
      name= name.replace(" ", "+");
      GeoLocation geolocation = new GeoLocation(name);
      String responseJson = geolocation.handleRequest();
      return responseJson;
  }
}

The Above java class handles the request, with name as the input param.

相關文章
相關標籤/搜索