This post describes how to set your custom JSON converter in Retrofit. There are more posts in the Retrofit series. Find previous posts in the list below
Retrofit Series Overview
- Getting Started and Creating an Android Client
- Basics of API Description
- Creating a Sustainable Android Client
- URL Handling, Resolution and Parsing
- How to Change API Base Url at Runtime
- Multiple Server Environments (Develop, Staging, Production)
- Share OkHttp Client and Converters between Retrofit Instances
- Upgrade Guide from 1.9
- Beyond Android: Retrofit for Java Projects
- How to use OkHttp 3 with Retrofit 1
- Synchronous and Asynchronous Requests
- Send Objects in Request Body
- Add Custom Request Header
- Manage Request Headers in OkHttp Interceptor
- Dynamic Request Headers with @HeaderMap
- Multiple Query Parameters of Same Name
- Optional Query Parameters
- Send Data Form-Urlencoded
- Send Data Form-Urlencoded Using FieldMap
- How to Add Query Parameters to Every Request
- Add Multiple Query Parameter With QueryMap
- How to Use Dynamic Urls for Requests
- Constant, Default and Logic Values for POST and PUT Requests
- Cancel Requests
- Reuse and Analyze Requests
- Optional Path Parameters
- How to Send Plain Text Request Body
- Customize Network Timeouts
- How to Trust Unsafe SSL certificates (Self-signed, Expired)
- Dynamic Endpoint-Dependent Interceptor Actions
- How to Update Objects on the Server (PUT vs. PATCH)
- How to Delete Objects on the Server
- Introduction to (Multiple) Converters
- Adding & Customizing the Gson Converter
- Implementing Custom Converters
- How to Integrate XML Converter
- Access Mapped Objects and Raw Response Payload
- Supporting JSON and XML Responses Concurrently
- Handling of Empty Server Responses with Custom Converter
- Send JSON Requests and Receive XML Responses (or vice versa)
- Unwrapping Envelope Responses with Custom Converter
- Wrapping Requests in Envelope with Custom Converter
- Define a Custom Response Converter
Basics
Retrofit ships with Google's JSON by default. Every JSON mapping is done with the help of GSON. Sometimes, your framework or attitude requires to change the integrated JSON converter. One of the well known converters is Jackson. We'll use Jackson for the code examples.
Existing Retrofit Converters
Besides GSON, Retrofit can be configured with various content formats. The retrofit-converters
directory lists existing response converts:
The integration with gradle can be done with these commands:
compile 'com.squareup.retrofit:converter-<converter-name>:1.9.0'
# e.g. Jackson
compile 'com.squareup.retrofit:converter-jackson:1.9.0'
# e.g. XML
compile 'com.squareup.retrofit:converter-simplexml:1.9.0'
You probably know how to do with protocol buffers :)
Create Your Own Converter
In case you need or want to create your own Retrofit response converter, you can follow the steps below. We'll use Jackson library to illustrate the concrete definition and handling.
Remember: There are existing Retrofit converters and you can use them directly by integrating the respective gradle dependency. The list above depicts existing converters which are shipped as a separate gradle dependency and can be easily integrated with Retrofit.
Jackson Gradle Dependency
At first, define the Jackson dependency. This example uses Jackson 2.x which ships with a different group and artifact id than previous Jackson 1.x. Add the required Maven repository and compile dependency.
repositories {
maven { url "http://repository.codehaus.org/org/codehaus" }
}
dependencies {
compile 'com.fasterxml.jackson.core:jackson-databind:2.4.3'
}
Implement Your Custom JSON Converter
The important part to replace the JSON converter of Retrofit is to implement the Converter
interface and override its two methods: fromBody
and toBody
. Both methods handle the conversion from and to JSON.
public class JacksonConverter implements Converter {
private ObjectMapper mapper = new ObjectMapper();
@Override
public Object fromBody(TypedInput body, Type type) throws ConversionException {
JavaType javaType = mapper.getTypeFactory().constructType(type);
try {
return mapper.readValue(body.in(), javaType);
} catch (IOException e) {
throw new ConversionException(e);
}
}
@Override
public TypedOutput toBody(Object object) {
try {
String charset = "UTF-8";
String json = mapper.writeValueAsString(object);
return new JsonTypedOutput(json.getBytes(charset));
} catch (IOException e) {
throw new AssertionError(e);
}
}
private static class JsonTypedOutput implements TypedOutput {
private final byte[] jsonBytes;
JsonTypedOutput(byte[] jsonBytes) { this.jsonBytes = jsonBytes; }
@Override public String fileName() { return null; }
@Override public String mimeType() { return "application/json; charset=UTF-8"; }
@Override public long length() { return jsonBytes.length; }
@Override public void writeTo(OutputStream out) throws IOException { out.write(jsonBytes); }
}
The JsonTypedOutput
class is used to set the correct mimeType. Since the output type is JSON, the mime type should be application/json
, too.
Set Your Custom JSON Converter
The JSON converter of Retrofit is integrated in the RestAdapter
. Changing the converter can be done by calling the setConverter()
method on your rest adapter object. Further, when creating a rest client, you can integrate the jackson converter by setting the converter directly during rest adapters build process.
// Create our Converter
JacksonConverter jacksonConverter = new JacksonConverter();
// Build the Retrofit REST adaptor pointing to the URL specified, with the Converter.
// Note: The Converter must be set before the .build() command
RestAdapter restAdapter = new RestAdapter.Builder()
.setConverter(jacksonConverter)
.setEndpoint("https://api.example.com/")
.build();
Great! Now, all your created Rest adapters will use the JacksonConverter for JSON handling.
In case you run into problems or questions, please get in touch on Twitter @futurestud_io.