【问题标题】:Android POST method stopped workingAndroid POST 方法停止工作
【发布时间】:2017-04-05 06:51:26
【问题描述】:

我有一个 android 应用程序,它使用我的 Web 服务器中的一些 POST 方法。在 3 天之前,我的应用程序在每台 android 设备上运行顺利。今天我遇到了一个问题,我的 https POST 调用仅适用于 android 设备 6.0。版本。我还有一些设备(5.0 和 4.3.x),在它们上相同的应用程序无法与我的 WEB 服务器建立通信。我已经与拥有我的 Web 服务器的托管公司进行了交谈,他们告诉我他们在过去三天内没有改变任何事情。奇怪的是,相同的代码在 api 23 上工作,但在比这更少的 api 上工作(测试 5.0。和 4.3.x)。所以我的问题是,在过去的三天里,我没有注意到来自 android 的 https 调用发生了什么变化吗?

我从 android 进行 https 调用的代码如下(AsyncTask)

protected String doInBackground(Object... params) {
    String param1="a";
    String param2 = "b";
    HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
    DefaultHttpClient client = new DefaultHttpClient();
    SchemeRegistry registry = new SchemeRegistry();
    SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
    socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
    //registry.register(new Scheme("http", socketFactory, 80));
    registry.register(new Scheme("https", socketFactory, 443));
    SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
    DefaultHttpClient httpclient = new DefaultHttpClient(mgr, client.getParams());

    // Set verifier
    HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

    // Example send http request
    final String url = Config.url_login_async_task;
    HttpPost httppost = new HttpPost(url);

    try {
        // Add your data
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("param1", param1));
        nameValuePairs.add(new BasicNameValuePair("param2", param2));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        // Execute HTTP Post Request
        response = httpclient.execute(httppost);

    } catch (ClientProtocolException e) {
    } catch (IOException e) {
    }
    try {
        //Log.d("response", response.toString());
        odgovor = EntityUtils.toString(response.getEntity());
    } catch (ParseException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return odgovor;
}

我有点困惑,因为应用程序在某些设备上停止正常工作,而在某些设备上却没有,我想知道这是为什么。

编辑:添加项目 gradle

buildscript {
repositories {
    jcenter()
}
dependencies {
    classpath 'com.android.tools.build:gradle:1.3.0'

    // NOTE: Do not place your application dependencies here; they belong
    // in the individual module build.gradle files
  }
 }

allprojects {
repositories {
    jcenter()
}
}

模块摇篮

apply plugin: 'com.android.application'

android {

    compileSdkVersion 23
    buildToolsVersion "23.0.1"
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES.txt'
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/dependencies.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/LGPL2.1'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/notice.txt'
    }
    defaultConfig {
        applicationId "com.x.y.z"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.google.android.gms:play-services:7.8.0'
}

编辑 2:

尝试在android {} 中添加useLibrary 'org.apache.http.legacy' 以及来自其他链接的所有其他解决方案,但仍然没有成功。我读到了这个“已弃用”的 apache 库,奇怪的是,在低于 API 22 的设备上,我的应用程序崩溃(它应该可以工作,因为在那些 api lvls 上它应该可以工作)并且在 API 23 上它可以工作(它不应该因为在 API 23 上已弃用。

编辑 3:新错误

经过仔细调试并花费数小时尝试查找错误后,我在日志中发现了下一个错误

未能在表面 0xa379c740 上设置 EGL_SWAP_BEHAVIOR,错误=EGL_SUCCESS javax.net.ssl.SSLPeerUnverifiedException:没有对等证书 在 com.android.org.conscrypt.SSLNullSession.getPeerCertificates(SSLNullSession.java:104) 在 org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:98) 在 org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:393) 在 org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:170) 在 org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169) 在 org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124) 在 org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365) 在 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:560) 在 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:492) 在 org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:470)

有人可以尝试用发生此错误的证书向我解释服务器上发生了什么吗?

【问题讨论】:

  • 你能解释一下为什么应用程序在没有任何代码更改的情况下停止工作吗?
  • 因为可能会被弃用。我建议你查看 Volley、Retrofit 和 OkHttp 等网络库
  • 你的目标api是22或以下,对吗?
  • 不,我的目标 api 是 23,它适用于 api 23,但在较低的 api 上我无法运行那些 post 方法。

标签: android https http-post


【解决方案1】:

此问题基于 HTTPS:服务器中的安全异常,一旦在托管域中更新您的 SSL,您将得到正确的响应,否则您将使用以下代码

HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
DefaultHttpClient httpClient = new DefaultHttpClient();
SchemeRegistry registry = new SchemeRegistry();
SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
registry.register(new Scheme("https", socketFactory, 443));
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
SingleClientConnManager mgr = new SingleClientConnManager(httpClient.getParams(), registry);
DefaultHttpClient client = new DefaultHttpClient(mgr, httpClient.getParams());

// Set verifier
HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

DefaultHttpClient client=new DefaultHttpClient();
HttpPost request = new HttpPost(url);
request.setEntity(new StringEntity(jobject.toString()));
request.setHeader("Content-type", "application/json");
HttpResponse response = client.execute(request);
HttpEntity resEntity = response.getEntity();
String json = EntityUtils.toString(resEntity);

【讨论】:

猜你喜欢
  • 2018-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 2021-12-15
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多