使用Retrofit2的HTTP请求获取“不支持CLEARTEXT通信”错误

时间:2016-07-16 13:23:34

标签: android android-studio retrofit retrofit2

我的Api界面有一个请求:

@FormUrlEncoded
@POST(ApiStatics.authorizeURL)
Call<Oauth2Model> authorizer(@Field("grant_type") String grantType,
                             @Field("username") String userName,
                             @Field("password") String password,
                             @Field("client_id") String clientID,
                             @Field("client_secret") String clientSecret);

使用此getApi方法:

public static MyAPI getApi() {
    if (api == null) {
        OkHttpClient client;
        if (GuildsApp.isDebug()) {
            HttpLoggingInterceptor bodyInterceptor = new HttpLoggingInterceptor();
            bodyInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            HttpLoggingInterceptor headerInterceptor = new HttpLoggingInterceptor();
            headerInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
            client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).writeTimeout(5, TimeUnit.MINUTES).connectTimeout(5, TimeUnit.MINUTES).addInterceptor(bodyInterceptor).addInterceptor(headerInterceptor).build();
        } else {
            client = new OkHttpClient.Builder().readTimeout(5, TimeUnit.MINUTES).writeTimeout(5, TimeUnit.MINUTES).connectTimeout(5, TimeUnit.MINUTES).build();
        }
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.baseUrl(BASE_URL);
        builder.addConverterFactory(GsonConverterFactory.create());
        builder.client(client);
        Retrofit retrofit = builder.build();
        api = retrofit.create(MyAPI.class);
    }
    return api;
}

我用这个方法在我的片段中使用这个api:

private void login(String user, String pass) {
    ApiManager.getApi().authorizer("password", user, pass, ApiStatics.CID,ApiStatics.CSecret).enqueue(new Callback<Oauth2Model>() {
        @Override
        public void onResponse(Call<Oauth2Model> call, Response<Oauth2Model> response) {
            Log.e("authorize token",""+response.body().access_token);
        }

        @Override
        public void onFailure(Call<Oauth2Model> call, Throwable t) {
            Log.e("Failure ",""+t.getLocalizedMessage());
        }
    });
}

当我运行项目时,请使用此日志请求调用onFailure方法:

  

E /失败:不支持明文通信:[ConnectionSpec的(密码组= [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA],tlsVersions = [TLS_1_2, TLS_1_1,TLS_1_0],supportsTlsExtensions =真),ConnectionSpec的(密码组= [TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SH A256,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_3DES_EDE_CBC_SHA],tlsVersions = [TLS_1_0],supportsTlsExtensions = true)]

我的BASE_URL是HTTP,而不是HTTPS。 我的登录方法用login(“”,“”)调用;在服务器上接受“” 我该如何解决这个错误? 我使用Retrofit 2.1.0,我的测试设备是nexus 5x android N

2 个答案:

答案 0 :(得分:2)

在课程顶部添加此注释。

@PowerMockIgnore("javax.net.ssl.*")

它会忽略SSL检查。

答案 1 :(得分:1)

通过在我的片段中添加一个简单的getApi方法而不是ApiManager,问题解决了!

private MyAPI getApi(){
    Retrofit.Builder builder = new Retrofit.Builder();
    builder.baseUrl(ApiManager.BASE_URL);
    builder.addConverterFactory(GsonConverterFactory.create());
    Retrofit retrofit = builder.build();
    return retrofit.create(MyAPI.class);
}

我的登录方法现在是:

private void login(String user, String pass) {
getApi().authorizer("password", user, pass, ApiStatics.CID,ApiStatics.CSecret).enqueue(new Callback<Oauth2Model>() {
    @Override
    public void onResponse(Call<Oauth2Model> call, Response<Oauth2Model> response) {
        Log.e("authorize token",""+response.body().access_token);
    }

    @Override
    public void onFailure(Call<Oauth2Model> call, Throwable t) {
        Log.e("Failure ",""+t.getLocalizedMessage());
    }
});
}

有些机构可以向我解释一下在我的ApiManager和我的片段中实现getApi方法有什么区别吗?