0

In my app I use Retrofit+Gson to communicate with the server. However, there is encoding problem with the server response.
In OkHttp logging interceptor server response look like this, which is OK:

... "name":"S\u0026#39;mores" ...

This is part of server response JSON. When the response is deserialized by Gson, the deserialized string looks like this:

S'mores

I'd like to know what's happening during deserialization and how to make Strings be encoded properly.
Below is my Retrofit initialization code:

val client = OkHttpClient.Builder()
            .addInterceptor(
                HttpLoggingInterceptor()
                    .setLevel(HttpLoggingInterceptor.Level.BODY)
            )

mRetrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .client(client.build())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createAsync())
            .addConverterFactory(GsonConverterFactory.create())
            .build()

        mAPI = mRetrofit.create(PetfinderJSONAPI::class.java)

What I tried:

  • Set gson.disableHtmlEscaping() and pass it to GsonConverterFactory.create()
  • Add OkHttp Interceptor which sets Accept-Charset: utf-8
  • Manually decode String before setting it to text field by URLDecoder.decode() and Html.fromHtml()

Neither of these helped. My strings are still not properly encoded.

EDIT: According to this html decoder site, ' is decoded as '. Thus, I expect my decoded string to be S'mores

Mexator
  • 136
  • 2
  • 10

2 Answers2

0

The unicode \u0026 refers to hex value 26, or 38 in decimal. ASCII 38 indicates an Ampersand(&). https://www.ascii-code.com/

  • Yeah, thank you. Now I see that server sends HTML encoded data, which is then encoded in utf-8. So, how do I use Gson+Retrofit to decode it? – Mexator Jun 30 '20 at 14:41
0

Well, I found an answer for the similar older question: https://stackoverflow.com/a/52524583/10267053

Just like there, I created custom deserializer:

class HtmlDeserializer: JsonDeserializer<String> {
    @Throws(JsonParseException::class)
    override fun deserialize(
        json: JsonElement, typeOfT: Type?,
        context: JsonDeserializationContext?
    ): String? {
        return StringEscapeUtils.unescapeHtml4(json.asString)
    }
}
Mexator
  • 136
  • 2
  • 10