最新 Okhttp 中的主机拦截器 HttpUrl.parse IllegalArguementException

Host interceptor HttpUrl.parse IllegalArguementException in latest Okhttp

I have to intercept host at run time . As my url is dynamic. below code is working fine in old okhttp3

使用旧 Okhttp

class HostSelectionInterceptor @Inject constructor(val chiPrefs: ChiPrefs): Interceptor{

    override fun intercept(chain: Interceptor.Chain): Response {
        var request: Request = chain.request()

        var host = String.format(Locale.ENGLISH, "https://%s.cognitiveintl.com",
            chiPrefs.sitePrefix())

        request.url().pathSegments().forEach {
            host += "/$it"
        }

        if(host.isNotEmpty()){
            val newUrl = HttpUrl.parse(host)
            request = request.newBuilder().url(newUrl!!).build()
        }
        return chain.proceed(request)
    }
}

但在升级到最新版本后。

val newUrl = HttpUrl.parse(host) // deprecated..

HttpUrl.parse。被弃用..

在研发之后,我像这样更新我的代码

val newUrl = request.url.newBuilder()
    .host(host) ///crashed at this line 
    .build()
request = request.newBuilder()
    .url(newUrl)
    .build()

它给出 IllegalArguementException 。提出解决方案。

崩溃:

FATAL EXCEPTION: OkHttp Dispatcher
    Process: com.chi.doctorapp.dev, PID: 2906
    java.lang.IllegalArgumentException: unexpected host: https://chi-dev1.cognitiveintl.com/api/doctor_app/GetProfile
        at okhttp3.HttpUrl$Builder.host(HttpUrl.kt:961)
        at com.chi.doctorapp.di.interceptors.HostSelectionInterceptor.intercept(HostSelectionInterceptor.kt:28)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:100)

替换为:

HttpUrl.parse(host)

有了这个:

host.toHttpUrlOrNull()

您需要导入:

import okhttp3.HttpUrl.Companion.toHttpUrlOrNull()

这在 upgrade guide 中有记录。

正在使用

 request.url.newBuilder()
    .host(host)
    .build()

才是正确的方法。

您崩溃的原因是作为主机传递了完整的 url。
例如对于 url https://subdomain.example.com/some/path 主机是 subdomain.example.com

所以试试这个:

class HostSelectionInterceptor @Inject constructor(val chiPrefs: ChiPrefs): Interceptor{

    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        
        //Notice the removed "https://"
        val host = String.format(Locale.ENGLISH, "%s.weburlintl.com",
            chiPrefs.sitePrefix())

        // This will keep the path, query parameters, etc.
        val newUrl = request.url.newBuilder()
            .host(host)
            .build()

        val newRequest = request
            .newBuilder()
            .url(newUrl)
            .build()

        return chain.proceed(newRequest)
    }
}