main.name.remal.gradle_plugins.utils.newJsonRetrofitBuilder.kt Maven / Gradle / Ivy
package name.remal.gradle_plugins.utils
import com.fasterxml.jackson.databind.JavaType
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Converter
import retrofit2.Retrofit
import java.lang.reflect.Type
import java.nio.charset.StandardCharsets.UTF_8
fun newJsonRetrofitBuilder(httpClientConfigurer: (httpClientBuilder: OkHttpClient.Builder) -> OkHttpClient.Builder = { it }): Retrofit.Builder {
return newRetrofitBuilder {
httpClientConfigurer(it.addInterceptor {
it.proceed(
it.request().newBuilder()
.addHeader("Accept", "application/json")
.build()
)
})
}
.addConverterFactory(JsonConverterFactory)
}
private object JsonConverterFactory : Converter.Factory() {
override fun requestBodyConverter(type: Type, parameterAnnotations: Array, methodAnnotations: Array, retrofit: Retrofit): Converter<*, RequestBody>? {
return JsonRequestBodyConverter(type)
}
override fun responseBodyConverter(type: Type, annotations: Array, retrofit: Retrofit): Converter? {
return JsonResponseBodyConverter(type)
}
}
private class JsonRequestBodyConverter(type: Type) : Converter {
companion object {
private val CHARSET = UTF_8
private val MEDIA_TYPE = MediaType.get("application/json;charset=${CHARSET.name()}")
}
private val javaType = JSON_OBJECT_MAPPER.typeFactory.constructType(type)
private val writer = JSON_OBJECT_MAPPER.writerFor(javaType)
override fun convert(value: Any?): RequestBody? {
val json = JSON_OBJECT_MAPPER.writeValueAsString(value)
val bytes = json.toByteArray(CHARSET)
return RequestBody.create(MEDIA_TYPE, bytes)
}
}
private class JsonResponseBodyConverter(type: Type) : Converter {
private val javaType = JSON_OBJECT_MAPPER.typeFactory.constructType(type)
private val reader = JSON_OBJECT_MAPPER.readerFor(javaType)
override fun convert(responseBody: ResponseBody): Any? {
try {
val content = responseBody.string()
try {
return reader.readValue(content)
} catch (e: Throwable) {
throw JsonParseException(content, javaType, e)
}
} finally {
responseBody.close()
}
}
}
private class JsonParseException(content: String, javaType: JavaType, cause: Throwable) : RuntimeException(
buildString {
append("JSON can't be deserialized to ").append(javaType).append(": ")
val maxLength = 1024
if (content.length <= maxLength) {
append(content)
} else {
append(content.substring(0, maxLength))
append(" [ ... ").append(content.length - maxLength).append(" more characters ... ]")
}
},
cause
)
internal fun __parseWithRetrofitJsonObjectMapper(content: String, type: Class): T = JSON_OBJECT_MAPPER.readValue(content, type)
© 2015 - 2024 Weber Informatics LLC | Privacy Policy