Android 如何使用 AsyncHttpClient 进行 HTTPS 调用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21833804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:10:29  来源:igfitidea点击:

how to make HTTPS calls using AsyncHttpClient?

androidnetworkinghttpsandroid-async-http

提问by r4jiv007

i was using AsyncHttpClientlinkfor making http calls but now our server has migrated to HTTPS and I am getting exception javax.net.ssl.SSLPeerUnverifiedException: No peer certificate. Has anyone tried making https call using this library ?

我正在使用AsyncHttpClient链接进行 http 调用,但现在我们的服务器已迁移到 HTTPS,并且出现异常javax.net.ssl.SSLPeerUnverifiedException: No peer certificate。有没有人试过使用这个库进行 https 调用?

initialization of AsyncHttpClient :-

AsyncHttpClient 的初始化:-

AsyncHttpClient client = new AsyncHttpClient();
            PersistentCookieStore myCookieStore = new PersistentCookieStore(
                    getActivity());
            // List<Cookie> cookies = myCookieStore.getCookies();
            myCookieStore.clear();
            // cookies = myCookieStore.getCookies();
            client.setCookieStore(myCookieStore);

            client.get(loginUrl, new JsonHttpResponseHandler() {

                @Override
                public void onStart() {
                    super.onStart();
                    progressBar.setVisibility(View.VISIBLE);
                }

                @Override
                public void onFinish() {
                    super.onFinish();
                    progressBar.setVisibility(View.GONE);
                }

                @Override
                public void onSuccess(int statusCode, JSONObject userInfo) {
                    super.onSuccess(statusCode, userInfo);

                    String errorMsg = null;
                    try {
                        errorMsg = userInfo.getString("error");
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }

                    if (errorMsg != null) {
                        errorMsg = getActivity().getResources().getString(
                                R.string.loginFailure)
                                + "\nError: " + errorMsg;
                        tvLoginFailure.setText(errorMsg);
                        tvLoginFailure.setVisibility(View.VISIBLE);

                    } else {
                        Subscriber.setEmail(email);
                        Subscriber.setPassword(password);
                        LoginUtility.saveUserInfo(getActivity(), userInfo);

                        if (Subscriber.getStatus().contentEquals("ACTIVE")) {
                            Intent intent;
                            if (MyApplication.ottMode) {
                                intent = new Intent(getActivity(),
                                        OTTMainScreen.class);

                            } else {
                                intent = new Intent(getActivity(),
                                        MainActivity.class);
                                intent.putExtra("SIGNEDIN", true);
                            }
                            if (MyApplication.ottMode) {
                                Utility.playSound(getActivity());
                            }
                            startActivity(intent);
                            getActivity().finish();

                        } else if (Subscriber.getStatus().contentEquals(
                                "SUSPENDED")) {
                            try {
                                String suspendedReason = userInfo
                                        .getString("suspendreason");
                                if (suspendedReason != null
                                        && suspendedReason
                                                .contentEquals("NO_SUBSCRIPTION")) {

                                    new AlertDialog.Builder(getActivity())
                                            .setIcon(
                                                    android.R.drawable.ic_dialog_alert)
                                            .setTitle("Account Suspended")
                                            .setMessage(
                                                    "Your account doesn't have any active subscription. You need to subscribe to a Package before you can proceed.")
                                            .setPositiveButton(
                                                    "Subscribe",
                                                    new DialogInterface.OnClickListener() {
                                                        public void onClick(
                                                                DialogInterface dialog,
                                                                int which) {
                                                            recreatePackage();
                                                        }
                                                    })
                                            .setNegativeButton("Cancel", null)
                                            .show();

                                } else {
                                    // TODO
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                        } else if (Subscriber.getStatus().contentEquals("INIT")) {
                            // TODO
                        }
                    }
                }

                @Override
                public void onFailure(int statusCode,
                        org.apache.http.Header[] headers, String responseBody,
                        Throwable e) {
                    super.onFailure(statusCode, headers, responseBody, e);
                    String msg = getActivity().getResources().getString(
                            R.string.loginFailure)
                            + "\nError: " + responseBody;
                    tvLoginFailure.setText(msg);
                    tvLoginFailure.setVisibility(View.VISIBLE);
                }
            });

回答by vzamanillo

You need import the public server certificate into your default keystore, or if you are not interested in the authentication of your client you can initialize the AsyncHttpClientwith

您需要将公共服务器证书导入您的默认密钥库,或者如果您对客户端的身份验证不感兴趣,您可以AsyncHttpClient使用

AsyncHttpClient asycnHttpClient = new AsyncHttpClient(true, 80, 443);

but this trick is not secure because use a custom SSLSocketFactoryimplementation whos omit the SSL certificate validation, take a look at the AsyncHttpClientsource code.

但是这个技巧并不安全,因为使用省略 SSL 证书验证的自定义SSLSocketFactory实现,请查看AsyncHttpClient源代码。

More information about SSLSocketFactory at https://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

有关 SSLSocketFactory 的更多信息,访问https://developer.android.com/reference/org/apache/http/conn/ssl/SSLSocketFactory.html

回答by JavadKhan

you can also solve this problem, with adding this 1 line.

您也可以通过添加此 1 行来解决此问题。

asyncHttpClient.setSSLSocketFactory(MySSLSocketFactory.getFixedSocketFactory());

回答by Manuel Spigolon

I have a simple http client that calls https service:

我有一个调用 https 服务的简单 http 客户端:

import android.util.Log;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;

/**
 */
public class HttpSimpleClient {

    private static final String TAG = HttpSimpleClient.class.getSimpleName();

    private static HttpSimpleClient instance;

    private HttpSimpleClient(){}

    public static HttpSimpleClient instance(){
        if (instance==null) {
            instance = new HttpSimpleClient();
        }
        return instance;
    }

    public <T> T post(URL url,
                      List<NameValuePair> header,
                      List<NameValuePair> parameter,
                      ResponseHandler<T> responseHandler) throws IOException {
        return post(url, header, parameter, responseHandler, null, null);
    }

    public <T> T post(URL url,
                     List<NameValuePair> header,
                     List<NameValuePair> parameter,
                     ResponseHandler<T> responseHandler,
                     AuthScope proxy,
                     UsernamePasswordCredentials proxyUser) throws IOException {
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost request = new HttpPost(url.toString());

        if (header!=null) {
            for (NameValuePair head : header){
                request.setHeader(head.getName(), head.getValue());
            }
            Log.d(TAG, "Aggiunti header: "+ header.size());

        } else {
            // Header di default
            request.setHeader("Content-Type", "application/x-www-form-urlencoded");
            request.setHeader("User-Agent", System.getProperty("http.agent"));
            Log.d(TAG, "Aggiunti header di defautl");
        }

        if (parameter!=null) {
            request.setEntity(new UrlEncodedFormEntity(parameter, HTTP.UTF_8));
            Log.d(TAG, "Aggiunti parametri: "+ parameter.size());
        }


        if (proxy!=null) {
            if (proxyUser!=null) {
                ((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(proxy, proxyUser);

            } else {
                // TODO gestire proxy senza credenziali
                ((AbstractHttpClient) httpClient).getCredentialsProvider().setCredentials(proxy, null);

            }
            Log.d(TAG, "Impostato Proxy per la connessione");
        }
        return httpClient.execute(request, responseHandler);
    }


    public static String httpResponseToString(HttpResponse httpResponse, int bufferSize) throws IOException {
        InputStream content = httpResponse.getEntity().getContent();

        int numRead;
        byte[] buffer = new byte[bufferSize];
        ByteArrayOutputStream outString = new ByteArrayOutputStream();
        try{
            while ((numRead = content.read(buffer)) != -1) {
                outString.write(buffer, 0, numRead);
            }
        } finally {
            content.close();
        }
        return new String(outString.toByteArray());
    }
}

And i use it in a AsyncTask:

我在 AsyncTask 中使用它:

response = HttpSimpleClient.instance().post(
                    getServiceURL(), // HTTPS url
                    mHeader, // List<NameValuePair>
                    mParameter, // List<NameValuePair>
                    getResponseHandler() // org.apache.http.client.ResponseHandler
            );

Tested on Android api>=10

在Android api上测试>=10

回答by Rajesh Kumar

Here is my code:

这是我的代码:

private Map<String, String> mParams;

public void sendata(View v) throws JSONException {
    username = (EditText) findViewById(R.id.txtusername);
    password = (EditText) findViewById(R.id.txtpassword);

    final ProgressDialog pDialog = new ProgressDialog(this);
    pDialog.setMessage("Loading...");
    pDialog.show();
    JSONObject j = new JSONObject();
    j.put("password", password.getText());
    j.put("username", username.getText());
    j.put("Deviceid", 123456789);
    j.put("RoleId", 1);
    String url = Url;
    AsyncHttpClient client = new AsyncHttpClient();
    RequestParams params = new RequestParams();
    params.put("json", j.toString());
    client.post(url, params, new JsonHttpResponseHandler() {
        @SuppressLint("NewApi")
        public void onSuccess(JSONObject response) {
            pDialog.hide();
            JSONObject jsnObjct;
            try {
                JSONObject json = (JSONObject) new JSONTokener(response
                        .toString()).nextValue();
                JSONObject json2 = json.getJSONObject("Data");
                JSONArray test = (JSONArray) json2
                        .getJSONArray("PatientAllergies");
                for (int i = 0; i < test.length(); i++) {
                    json = test.getJSONObject(i);
                    System.out.print(json.getString("PatientId"));
                    System.out.print(json.getString("Id"));
                    System.out.print(json.getString("AllergyName"));
                    System.out.print(json.getString("Reaction"));
                    System.out.print(json.getString("OnSetDate"));
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        public void onFailure(int statusCode, Header[] headers, String res,
                Throwable t) {
            pDialog.hide();
        }
    });

}
JSONObject jsonObject;

private void parsejson(JSONObject response) {

    try {
        jsonObject = response;
        System.out.print(response.toString());
        JSONObject jsnObjct = jsonObject.getJSONObject("Data");
        System.out.print(jsonObject.toString());
        jsnObjct = jsnObjct.getJSONObject("PhysicianDetail");

        System.out.print(jsnObjct.toString());

    } catch (JSONException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}