Android - отправка запроса HTTPS
Я хотел бы отправить запрос на получение HTTPS в API покупок Google, но у меня ничего не получается, например вот что я сейчас пытаюсь:
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;
}
Если у кого-то есть какие-либо предложения по улучшению или замене, пожалуйста, дайте мне знать, спасибо заранее.
7 ответов
Вы должны получить ошибку компиляции.
Это правильная версия:
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;
}
Поэтому теперь, если у вас есть ошибка, ваш ответ будет возвращен как нулевой.
Получив ответ и проверив его на null, вы захотите получить контент (т. Е. Ваш 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();
Это дает вам InputStream для работы. Если вы хотите преобразовать это в строку, вы должны сделать ниже или эквивалент:
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 "";
}
}
Когда у вас есть эта строка, вам нужно создать из нее JSONObject:
http://developer.android.com/reference/org/json/JSONObject.html
JSONObject json = new JSONObject(inputStreamAsString);
Готово!
Вы добавили это в свой манифест
<uses-permission android:name="android.permission.INTERNET" />
Вы можете попробовать это таким образом, возможно, используя класс URLConnection
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;
}
Я пишу два метода здесь. Скопируйте их оба. В вашем первом методе uri = ваш URL, который вы хотите отправить запрос:
Первый метод:
public static String Getdata (String uri ){
BufferedReader reader = null;
try {
URL url = new URL(uri);
HttpURLConnection con = null;
URL testUrlHttps = new URL(uri);
if (testUrlHttps.getProtocol().toLowerCase().equals("https"))
{
trustAllHosts();
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
https.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
con = https;
} else
{
con = (HttpURLConnection) url.openConnection();
}
con.setReadTimeout(15000);
con.setConnectTimeout(15000);
StringBuilder sb = new StringBuilder();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
return "";
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
return "";
}
}
}
}
и другой метод, который полностью доверяет всей сертификации для первого метода.
Второй метод:
private static void trustAllHosts()
{
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager()
{
public java.security.cert.X509Certificate[] getAcceptedIssuers()
{
return new java.security.cert.X509Certificate[] {};
}
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException
{
}
} };
// Install the all-trusting trust manager
try
{
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e)
{
e.printStackTrace();
}
}
Благодаря сделать HTTPS / HTTP-запрос в Android
Добавьте класс Java 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();
}
}
в вашем коде
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);
тоже работает в HttpPost.
Трудно сказать наверняка, если вы не скажете нам, в чем ошибка.
Но если вы выполняете это в потоке пользовательского интерфейса, а веб-серверу требуется более нескольких секунд, чтобы ответить, вы получите предупреждение "Приложение не отвечает" из системы. Убедитесь, что вы делаете какие-либо сетевые передачи в отдельном потоке.
Вы должны использовать HttpsURLConnection вместо httpClient
https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection