2017-07-24 96 views
3

我在我的Android應用程序中使用Retrofit2 + OkHttp3來創建GET - 請求REST服務器。問題是服務器沒有指定它提供的JSON的編碼。這導致'é'被接收爲' '(Unicode替換字符)。如何指定Get-Request編碼(Retrofit + OkHttp)

有沒有辦法告訴Retrofit或OkHttp哪個編碼響應?

這是我如何初始化改造(科特林代碼):

val gson = GsonBuilder() 
     .setDateFormat("d.M.yyyy") 
     .create() 

val client = OkHttpClient.Builder() 
     .build() 

val retrofit = Retrofit.Builder() 
     .baseUrl(RestService.BASE_URL) 
     .client(client) 
     .addConverterFactory(GsonConverterFactory.create(gson)) 
     .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
     .build() 

val rest = retrofit.create(RestService::class.java) 

PS:服務器是不是我的。所以我無法修復服務器端的最初問題。

編輯:最終的解決方案做這個

class EncodingInterceptor : Interceptor { 

    override fun intercept(chain: Interceptor.Chain): Response { 
     val response = chain.proceed(chain.request()) 
     val mediaType = MediaType.parse("application/json; charset=iso-8859-1") 
     val modifiedBody = ResponseBody.create(mediaType, response.body().bytes()) 
     val modifiedResponse = response.newBuilder() 
       .body(modifiedBody) 
       .build() 

     return modifiedResponse 
    } 
} 

回答

6

一種方式是建立一個Interceptor,是以響應,並設置適當的Content-Type像這樣:

class ResponseInterceptor : Interceptor { 
    override fun intercept(chain: Interceptor.Chain): Response { 
     val response = chain.proceed(chain.request()) 
     val modified = response.newBuilder() 
       .addHeader("Content-Type", "application/json; charset=utf-8") 
       .build() 

     return modified 
    } 
} 

你將它添加到您的OkHttp客戶端如此:

val client = OkHttpClient.Builder() 
     .addInterceptor(ResponseInterceptor()) 
     .build() 

您應該m請確保您只使用此OkHttpClient作爲未指定編碼的API,或者讓攔截器只添加相應端點的標頭,以避免覆蓋其他端點的有效內容類型標頭。

+0

哇,那很快。現在我只需要找出他們正在使用什麼編碼;) 謝謝你。 – Alexander

+0

好像OkHttp忽略了我設置的字符集。即使在添加正確的之前刪除舊的_Content-Type:application/json_之後。然而,我可以在攔截器中使用'InputStreamReader(response.body()。byteStream(),「ISO-8859-1」)。readText()'來獲得正確的字符串。但我無法將其添加到修改的響應中。 – Alexander

+0

我的第三個也是最後一個評論;)我得到它的工作,並將解決方案添加到我的問題。感謝您向我展示攔截器如何工作。 – Alexander