18

I would like to send a HTTPS Get Request to the google shopping api however nothing is quite working for me, for example here is what I'm trying at the moment:

try {        
    HttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet();
    request.setURI(new URI("https://www.googleapis.com/shopping/search/v1/public/products/?key={my_key}&country=&q=t-shirts&alt=json&rankByrelevancy="));
    HttpResponse response = client.execute(request);
} catch (URISyntaxException e) {
    e.printStackTrace();
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}   
return response;

If anyone has any suggestions on how to improve this or replace it please let me know, thanks in advance.

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Sam Jackson
  • 608
  • 1
  • 5
  • 13
  • 1
    Thats not your full code as in the scenario above the `response` variable is not in scope of the return statement. i.e. your declaring it within your try block so that just wouldn't work. Whats going wrong? – Blundell Apr 01 '12 at 20:44
  • I've edited my post to include the try bracket, but that is it. Should I remove the try and catch brackets and just use the 'throws exception...' so I can access the response variable? – Sam Jackson Apr 01 '12 at 21:24
  • 2
    What doesn't work? Any exception, Logcat? When problem came from httpClient, the first thing to do I recommended is always checking the response status code i.e. httpResponse.getStatusLine().getStatusCode(); – yorkw Apr 01 '12 at 21:26
  • I tried checking the response status like you suggested but it was underlined and gave an error, I used the log to find out what response was being returned as and it was "org.apache.http.message.BasicHttpResponse@46241178" however it doesn't really matter because it didn't force close this time. Do you know how I can use the response value, it's supposed to be returning an array in JSON format that I can parse but it doesn't look like it is. – Sam Jackson Apr 01 '12 at 22:16
  • Hope so you had solved your problem – Ishu Apr 02 '12 at 02:53

6 Answers6

41

You should be getting a compile error.

This is the correct version:

HttpResponse response = null;
try {        
    HttpClient client = new DefaultHttpClient();
    HttpGet request = new HttpGet();
    request.setURI(new URI("https://www.googleapis.com/shopping/search/v1/public/products/?key={my_key}&country=&q=t-shirts&alt=json&rankByrelevancy="));
    response = client.execute(request);
} catch (URISyntaxException e) {
    e.printStackTrace();
} catch (ClientProtocolException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}   
return response;

Therefore now if you have an error your response will be returned as null.

Once you have the response and checked it for null, you'll want to get the content (i.e. your JSON).

http://developer.android.com/reference/org/apache/http/HttpResponse.html http://developer.android.com/reference/org/apache/http/HttpEntity.html http://developer.android.com/reference/java/io/InputStream.html

response.getEntity().getContent();

This gives you an InputStream to work with. If you want to convert this to a string you'd do the below or equivalent:

http://www.mkyong.com/java/how-to-convert-inputstream-to-string-in-java/

public static String convertStreamToString(InputStream inputStream) throws IOException {
    if (inputStream != null) {
        Writer writer = new StringWriter();

        char[] buffer = new char[1024];
        try {
            Reader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"),1024);
            int n;
            while ((n = reader.read(buffer)) != -1) {
                writer.write(buffer, 0, n);
            }
        } finally {
            inputStream.close();
        }
        return writer.toString();
    } else {
        return "";
    }
}

When you have this string you need to create a JSONObject from it:

http://developer.android.com/reference/org/json/JSONObject.html

JSONObject json = new JSONObject(inputStreamAsString);

Done!

Josh Correia
  • 3,807
  • 3
  • 33
  • 50
Blundell
  • 75,855
  • 30
  • 208
  • 233
7

Did you add this to your manifest

<uses-permission android:name="android.permission.INTERNET" />
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
Helal Ismail
  • 518
  • 1
  • 10
  • 22
4

You can try it this way maybe using URLConnection class

String error = ""; // string field
private String getDataFromUrl(String demoIdUrl) {

    String result = null;
    int resCode;
    InputStream in;
    try {
        URL url = new URL(demoIdUrl);
        URLConnection urlConn = url.openConnection();

        HttpsURLConnection httpsConn = (HttpsURLConnection) urlConn;
        httpsConn.setAllowUserInteraction(false);
        httpsConn.setInstanceFollowRedirects(true);
        httpsConn.setRequestMethod("GET");
        httpsConn.connect();
        resCode = httpsConn.getResponseCode();

        if (resCode == HttpURLConnection.HTTP_OK) {
            in = httpsConn.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    in, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
            in.close();
            result = sb.toString();
        } else {
            error += resCode;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
}
SMagic
  • 317
  • 2
  • 10
  • java.lang.ClassCastException: com.android.okhttp.internal.http.HttpURLConnectionImpl cannot be cast to javax.net.ssl.HttpsURLConnection – beetree Sep 20 '16 at 23:17
  • If I use `HttpURLConnection` instead of `HttpsURLConnection` in this code, what will be the difference? As `HttpsURLConnection` inherits from `HttpURLConnection`, the same methods from the same instance will be called on `.connect` and `.getInputStream`. Am I wrong? – Mateus Pires Jan 23 '17 at 01:46
  • yes! [link] (https://developer.android.com/reference/java/net/HttpURLConnection.html) – SMagic Jan 23 '17 at 09:58
1

Thanks to Make HTTPS / HTTP Request in Android

Add a Java class CustomSSLSocketFactory.java

 import java.io.IOException;
 import java.net.Socket;
 import java.net.UnknownHostException;
 import java.security.KeyManagementException;
 import java.security.KeyStore;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
 import java.security.UnrecoverableKeyException;
 import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
 import org.apache.http.conn.ssl.SSLSocketFactory;

 public class CustomSSLSocketFactory extends SSLSocketFactory{
SSLContext sslContext = SSLContext.getInstance("TLS");
/**
 * Generate Certificate for ssl connection
 * @param truststore
 * @throws NoSuchAlgorithmException
 * @throws KeyManagementException
 * @throws KeyStoreException
 * @throws UnrecoverableKeyException
 */
public CustomSSLSocketFactory(KeyStore truststore)
        throws NoSuchAlgorithmException, KeyManagementException,
        KeyStoreException, UnrecoverableKeyException {
    super(truststore);
    TrustManager tm = new X509TrustManager(){
        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1)
                throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] chain,
                                       String authType) throws CertificateException {
        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };
    sslContext.init(null, new TrustManager[] {tm}, null);
}

@Override
public Socket createSocket(Socket socket, String host, int port,
                           boolean autoClose) throws IOException, UnknownHostException {
    return sslContext.getSocketFactory().createSocket(socket, host, port,
            autoClose);
}

@Override
public Socket createSocket() throws IOException {
    return sslContext.getSocketFactory().createSocket();
}
 }

in your code

    String cloud_url="https://www.google.com";
    HttpClient client = new DefaultHttpClient();
        if(cloud_url.toLowerCase().contains("https://")){
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);
            SSLSocketFactory sf = new CustomSSLSocketFactory(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
            client= new DefaultHttpClient(ccm, params);
        }


        HttpGet request= new HttpGet( );
        request.setURI(new URI( cloud_url));
        HttpResponse response = client.execute(request);

works in HttpPost too.

Joshy Francis
  • 340
  • 7
  • 13
0

You shall use HttpsURLConnection instead of httpClient

https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection

0

It's hard to say for sure if you don't tell us what the error is.

But if you are running this on the UI thread and the web server takes more than a few seconds to respond you will get an Application Not Responding warning from the system. Make sure that you do any network transfers on a separate thread.

Theasis
  • 91
  • 1
  • 4