1

i want to add a new date format to my simplexml retrofit converter, according to this :Parse date with SimpleFramework

class DateTransformer(format: String) : Transform<Date> {
    private val formatter = SimpleDateFormat(format) // SimpleDateFormat is not thread safe!
    @Throws(Exception::class)
    override fun read(value: String): Date {
        return formatter.parse(value)
    }

    @Throws(Exception::class)
    override fun write(value: Date): String {
        return formatter.format(value)
    }
}

i'm not sure how i can integrate it into the Retrofit converter, if at all, would love some input from you guys !

Thanks !

  • I recommend you avoid the `SimpleDateFormat` class. It is not only long outdated (along with `Date`), it is also notoriously troublesome. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Mar 23 '18 at 08:52

1 Answers1

1

According to the answer you linked, you can make SimpleXML parse a date by providing a RegistryMatcher to the Serializer.

Also, Retrofit's SimpleXml converter allows you to pass a Serializer to the SimpleXmlConverterFactory.

EDIT: Here's a full (base) example.

import okhttp3.Interceptor
import okhttp3.MediaType
import okhttp3.OkHttpClient
import okhttp3.Protocol
import okhttp3.Request
import okhttp3.Response
import okhttp3.ResponseBody
import org.simpleframework.xml.core.Persister
import org.simpleframework.xml.transform.RegistryMatcher
import org.simpleframework.xml.transform.Transform
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.simplexml.SimpleXmlConverterFactory
import retrofit2.http.GET
import java.text.SimpleDateFormat
import java.util.*

fun main(args: Array<String>) {
    val matcher = RegistryMatcher()
    val format = SimpleDateFormat("yyyy-MM-dd")
    matcher.bind(Date::class.java, DateTransformer(format))
    val serializer = Persister(matcher)

    val fakeHttpClient = createFakeHttpClient()
    val retrofit = Retrofit.Builder()
        .client(fakeHttpClient)
        .addConverterFactory(SimpleXmlConverterFactory.create(serializer))
        .baseUrl("http://localhost/")
        .build()

    val api = retrofit.create(MyFakeApi::class.java)
    val myData = api.callApi().execute().body()

    println(myData)
}

private fun createFakeHttpClient() = OkHttpClient.Builder()
    .addInterceptor(FakeInterceptor())
    .build()

class DateTransformer(private val format: SimpleDateFormat) : Transform<Date> {

    override fun write(value: Date?): String {
        return format.format(value)
    }

    override fun read(value: String?): Date {
        return format.parse(value)
    }

}

data class MyData @JvmOverloads constructor(var date: Date? = null, var title: String = "")

interface MyFakeApi {
    @GET("foo")
    fun callApi(): Call<MyData>
}

class FakeInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain?) = Response.Builder()
        .request(Request.Builder()
                     .url("http://localhost")
                     .build())
        .code(200)
        .body(ResponseBody.create(MediaType.parse("application/xml"), """
            <response>
                <date>2018-03-22</date>
                <title>Fake title</title>
            </response>
            """))
        .protocol(Protocol.HTTP_1_1)
        .message("")
        .build()
}
user2340612
  • 10,053
  • 4
  • 41
  • 66
  • 1
    @NoéMaillard consider accepting the answer if that solved your issue, otherwise provide more details about the error :) – user2340612 Mar 23 '18 at 10:20