google map geocode okhttp proxy

In order to call google-maps geocode web service, we used library google-maps-services-java,

https://github.com/googlemaps/google-maps-services-java

Sample of call geocdoe web service

https://maps.googleapis.com/maps/api/geocode/json?address=1%20kowloon

Since the keystore xx_egis.jks is configured for ssl trust store in wildfly with -Djavax.net.ssl.trustStore=xx_egis.jks, we have two ways to call the ssl web service,

1. bypass the ssl certificate validation

After investigation on the api of library google-maps-services-java, found that it did not expose the underly okhttp3.OkHttpClient, so it cannot apply following sample code to bypass ssl certificate validation,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
private static OkHttpClient.Builder configureToIgnoreCertificate(OkHttpClient.Builder builder) {
LOGGER.warn("Ignore Ssl Certificate");
try {

// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType)
throws CertificateException {
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};

// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();

builder.sslSocketFactory(sslSocketFactory, (X509TrustManager)trustAllCerts[0]);
builder.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
});
} catch (Exception e) {
LOGGER.warn("Exception while configuring IgnoreSslCertificate" + e, e);
}
return builder;
}

2. Add the ssl certificate to trust store (xx_egis.jks)

Run following command:

openssl s_client -connect maps.googleapis.com:443 -showcerts

Save the certificate (within —–BEGIN CERTIFICATE—– … —–END CERTIFICATE—–) as file google.maps.api.crt (reminder: save the root ca certificate, not the website certificate)

Import the certificate to trust store

keytool -import -trustcacerts -v -alias maps.googleapis.com -file google.maps.api.crt -keystore xx_egis.jks -storepass dxc.xx@2017

List the latest certificates in trust store, it should contain following entries,

1
2
3
4
5
6
7
8
9
10
11
keytool -list -keystore xx_egis.jks -storepass dxc.xx@2017
payment_signing, 201827日, trustedCertEntry,
憑證指紋 (SHA1): 6B:EA:31:51:8D:F8:81:3B:D8:D1:D8:0C:E7:22:12:21:96:E9:59:26
rootca, 2017822日, trustedCertEntry,
憑證指紋 (SHA1): C7:2C:81:6D:EB:2D:C7:36:63:90:D3:68:2D:57:F1:8F:C5:37:AF:DA
friendly3, 201819日, PrivateKeyEntry,
憑證指紋 (SHA1): CF:42:5A:D1:FB:A1:8F:AA:81:B5:76:F2:39:31:D6:4F:65:88:1A:A1
trust1, 2017822日, trustedCertEntry,
憑證指紋 (SHA1): C4:F1:83:51:20:55:BC:66:2F:D7:BA:F4:D4:7B:C9:43:95:9D:E2:D6
maps.googleapis.com, 2018725日, trustedCertEntry,
憑證指紋 (SHA1): EE:AC:BD:0C:B4:52:81:95:77:91:1E:1E:62:03:DB:26:2F:84:A3:18

My test program to call geocode web service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;

import com.google.maps.GeoApiContext;
import com.google.maps.GeocodingApi;
import com.google.maps.errors.ApiException;
import com.google.maps.model.GeocodingResult;
import com.google.maps.model.Geometry;

import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class ConnectionThrProxy {

public static void main(String[] args) throws IOException {
//normalCall();
//okhttpCall();
mapCall();
}

private static void normalCall() throws IOException {
//System.setProperty("http.proxyHost", "proxy1.govcloud.gov.hk");
//System.setProperty("http.proxyPort", "4005");

URL url = new URL("http://www.google.com/");

String proxyAddress = "proxy1.govcloud.gov.hk";
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, 4005));

URLConnection con = url.openConnection(proxy);

BufferedReader in = new BufferedReader(new InputStreamReader(
con.getInputStream()));

// Read it ...
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);

in.close();
}

private static void okhttpCall() throws IOException {
String proxyAddress = "proxy1.govcloud.gov.hk";
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, 4005));

OkHttpClient.Builder builder = new OkHttpClient.Builder().proxy(proxy);
OkHttpClient client = builder.build();

Request request = new Request.Builder()
.url("https://publicobject.com/helloworld.txt")
.build();

try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful())
throw new IOException("Unexpected code " + response);

Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}

System.out.println(response.body().string());
}
}

private static void mapCall() {
String googleMapKey = "key-id";
String proxyAddress = "proxy1.govcloud.gov.hk";
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyAddress, 4005));
GeoApiContext context = new GeoApiContext.Builder().apiKey(googleMapKey).proxy(proxy).build();

GeocodingResult[] results;

String address = "16 FLOOR EMPEROR COMMERCIAL CENTRE 39 DES VOEUX ROAD CENTRAL CENTRAL HONG KONG";
try {
results = GeocodingApi.geocode(context, address).await();
if (results.length > 0) {
Geometry geometry = results[0].geometry;

double lat = geometry.location.lat;
double lng = geometry.location.lng;
String locType = geometry.locationType.toString();
String formattedAddr = results[0].formattedAddress;
System.out.println("formattedAddr " + formattedAddr);

System.out.println("lat " + lat);
System.out.println("lng " + lng);
//printGeoResult(appl.getEngApplName(), results);
} else {
System.out.println("no geo result returned for address {}" + address);
}
} catch (ApiException | InterruptedException | IOException e) {
System.out.println("findGeoLocation" + e);
}

}
}

Run the program with showing detail debug message

Folder structure

1
2
3
4
5
6
7
8
9
10
11
ConnectionThrProxy.class

lib/
google-maps-services-0.2.8.jar
gson-2.8.0.jar
joda-time-2.10.jar
okhttp-3.8.1.jar
okio-1.13.0.jar
slf4j-api-1.7.24.jar

java -cp ".;lib/*" -Djavax.net.ssl.trustStore=xx_egis.jks -Djavax.net.debug=ssl test.ConnectionThrProxy

SSL debug parameter for reference
-Djavax.net.debug=ssl | -Djavax.net.debug=all