【问题标题】:Retrofit 2 unable to resolve host [closed]改造 2 无法解析主机 [关闭]
【发布时间】:2016-09-06 15:33:40
【问题描述】:

在我以前的应用程序版本中,我使用了 Apache 客户端,一切正常并且仍然​​正常。但由于一些性能提升,我们决定转向 Retrofit。问题是我每次都收到“无法解析主机“xxxxxx”:没有与主机名关联的地址”。

我把这个放在清单里

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

还有什么我忘记的吗?

这是网址:https://www.hbapimanager.azure-api.net/Wallet/CheckNumber

附:我已经为此苦苦挣扎了将近一周

已编辑:这是我的改造工厂类:

private static HttpLoggingInterceptor logging = new HttpLoggingInterceptor()
        .setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);

private static OkHttpClient.Builder httpClient = new OkHttpClient.Builder()
        .addInterceptor(logging);

private static HttpUrl url = new HttpUrl.Builder()
        .scheme("https")
        .host(Constants.Network.HOST)
        .build();

private static Retrofit.Builder builder =
        new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create());

public static <T> T createRetrofitService(final Class<T> clazz) {
    Retrofit retrofit = builder.client(httpClient.build()).build();
    return retrofit.create(clazz);
}

这是请求的接口

    @Headers({
        Constants.Network.HEADER_TYPE,
        Constants.Network.HEADER_KEY
})
@POST(Constants.Network.CHECK_NUMBER)
Call<StatusData> postCheckNumber(@Body CheckNumberPoRD checkNumberPoRD);

@Headers({
        Constants.Network.HEADER_TYPE,
        Constants.Network.HEADER_KEY
})
@GET(Constants.Network.CHECK_NUMBER)
Call<CheckNumberGRD> getCheckNumber(
        @Query("PrimaryKey") String primaryKey,
        @Query("RowKey") String rowKey
);

我明白了

09-06 16:58:50.958 7229-7283/kz.halykbank.halykewallet D/OkHttp: --> POST https://www.hbapimanager.azure-api.net/Wallet/CheckNumber http/1.1
09-06 16:58:50.959 7229-7283/kz.halykbank.halykewallet D/OkHttp: Content-   Type: application/json
09-06 16:58:50.959 7229-7283/kz.halykbank.halykewallet D/OkHttp: Content-Length: 27
09-06 16:58:50.959 7229-7283/kz.halykbank.halykewallet D/OkHttp: Ocp-Apim-Subscription-Key: xxxxxxxxxxxxxxxxxxxxxxxxx
09-06 16:58:50.959 7229-7283/kz.halykbank.halykewallet D/OkHttp: {"phone":"x(xxx)xxx-xx-xx"}
09-06 16:58:50.959 7229-7283/kz.halykbank.halykewallet D/OkHttp: --> END POST (27-byte body)
09-06 16:58:51.666 7229-7283/kz.halykbank.halykewallet D/OkHttp: <-- HTTP FAILED: java.net.UnknownHostException: Unable to resolve host "www.hbapimanager.azure-api.net": No address associated with hostname

【问题讨论】:

  • 你能发布更多你为实现改造而编写的代码
  • 从改造服务请求中去掉“/”
  • 你的基本 URL 和改造服务类是什么
  • @MoshErsan 我添加了网址
  • @EpicPandaForce,我添加了网址

标签: android android-manifest retrofit2


【解决方案1】:

我的问题是我试图向https://www.example.com 发送请求。但是,服务器的主机中没有 www.example.com,而只有 example.com。

【讨论】:

    【解决方案2】:
    HttpUrl baseUrl = new HttpUrl.Builder()
                    .scheme("https")
                    .host("www.hbapimanager.azure-api.net")
                    .encodedPath("/Wallet/")
                    .build();
    
    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .addInterceptor(new AdditionalHttpHeadersInterceptor(headersProvider))
                    .addInterceptor(httpLoggingInterceptor)
                    .build();
    
    ApiService apiService = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .client(okHttpClient)
                    .addConverterFactory(MoshiConverterFactory.create(moshi))
                    .build()
                    .create(ApiService.class);
    

    ApiService.java

    @Headers({
            Constants.Network.HEADER_TYPE,
            Constants.Network.HEADER_KEY
    })
    @GET(Constants.Network.CHECK_NUMBER)
    Call<CheckNumberGRD> getCheckNumber(
            @Query("PrimaryKey") String primaryKey,
            @Query("RowKey") String rowKey
    );
    

    其中Constants.Network.CHECK_NUMBER"CheckNumber",不带斜线

    但是,也许您必须设置自定义 ssl 套接字工厂,因为 https。最简单的方法是next:

    创建您的自定义 SSL 工厂类

    public class TLSSocketFactory extends SSLSocketFactory {
    
        private SSLSocketFactory internalSSLSocketFactory;
    
        public TLSSocketFactory() {
            SSLContext context = null;
            try {
                context = SSLContext.getInstance("TLS");
                context.init(null, null, null);
            } catch (NoSuchAlgorithmException | KeyManagementException e) {
                //TODO check it and fix
                throw new RuntimeException(e);
            }
            internalSSLSocketFactory = context.getSocketFactory();
        }
    
        @Override
        public String[] getDefaultCipherSuites() {
            return internalSSLSocketFactory.getDefaultCipherSuites();
        }
    
        @Override
        public String[] getSupportedCipherSuites() {
            return internalSSLSocketFactory.getSupportedCipherSuites();
        }
    
        @Override
        public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(s, host, port, autoClose));
        }
    
        @Override
        public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
        }
    
        @Override
        public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port, localHost, localPort));
        }
    
        @Override
        public Socket createSocket(InetAddress host, int port) throws IOException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(host, port));
        }
    
        @Override
        public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
            return enableTLSOnSocket(internalSSLSocketFactory.createSocket(address, port, localAddress, localPort));
        }
    
        private Socket enableTLSOnSocket(Socket socket) {
            if (socket != null && (socket instanceof SSLSocket)) {
                ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.1", "TLSv1.2"});
            }
            return socket;
        }
    }
    

    以及您的自定义 X509 信任管理器类

    public class CustomX509TrustManager implements X509TrustManager {
    
        @SuppressLint("TrustAllX509TrustManager")
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    
        @SuppressLint("TrustAllX509TrustManager")
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[]{};
        }
    }
    

    并创建您的 http 客户端

    OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .sslSocketFactory(new CustomX509TrustManager(), new TLSSocketFactory())
                    .addInterceptor(new AdditionalHttpHeadersInterceptor(headersProvider))
                    .addInterceptor(httpLoggingInterceptor)
                    .build();
    

    【讨论】:

    • 我已经试过了。 sslSocketFactory 没有帮助
    • 主机不存在。在check-host.net 和邮递员那里检查了它。也许您有自定义 DNS 服务器或使用 VPN 连接到此主机?
    【解决方案3】:

    您肯定会遇到您的基本 URL 如下所示的问题:

    http://blah.com/v1/blah
    

    你的服务看起来像

    @GET("/blah/blah/blah")
    

    但实际上你必须让它看起来像这样:

    http://blah.com/v1/blah/
    

    你的服务需要看起来像

    @GET("blah/blah/blah")
    

    【讨论】:

    • 很遗憾没有帮助
    • 这很难想象。那么这个网站就不存在了。
    • 这是一个棘手的部分。这个网站存在。我在 Android 和 Postman 上使用 Apache Client 对其进行了测试
    • @RustamIbragimov 你确定吗?我自己去那个地址甚至说DNS服务器无法解析它
    猜你喜欢
    • 2016-02-07
    • 1970-01-01
    • 2015-02-28
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多