Retrofit 2 Custom Xml Converter
suggest changeAdding dependencies into the build.gradle file.
dependencies { .... compile 'com.squareup.retrofit2:retrofit:2.1.0' compile ('com.thoughtworks.xstream:xstream:1.4.7') { exclude group: 'xmlpull', module: 'xmlpull' } .... }
Then create Converter Factory
public class XStreamXmlConverterFactory extends Converter.Factory { /** Create an instance using a default {@link com.thoughtworks.xstream.XStream} instance for conversion. */ public static XStreamXmlConverterFactory create() { return create(new XStream()); } /** Create an instance using {@code xStream} for conversion. */ public static XStreamXmlConverterFactory create(XStream xStream) { return new XStreamXmlConverterFactory(xStream); } private final XStream xStream; private XStreamXmlConverterFactory(XStream xStream) { if (xStream == null) throw new NullPointerException("xStream == null"); this.xStream = xStream; } @Override public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } Class<?> cls = (Class<?>) type; return new XStreamXmlResponseBodyConverter<>(cls, xStream); } @Override public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) { if (!(type instanceof Class)) { return null; } return new XStreamXmlRequestBodyConverter<>(xStream); } }
create a class to handle the body request.
final class XStreamXmlResponseBodyConverter <T> implements Converter<ResponseBody, T> { private final Class<T> cls; private final XStream xStream; XStreamXmlResponseBodyConverter(Class<T> cls, XStream xStream) { this.cls = cls; this.xStream = xStream; } @Override public T convert(ResponseBody value) throws IOException { try { this.xStream.processAnnotations(cls); Object object = this.xStream.fromXML(value.byteStream()); return (T) object; }finally { value.close(); } } }
create a class to handle the body response.
final class XStreamXmlRequestBodyConverter<T> implements Converter<T, RequestBody> { private static final MediaType MEDIA_TYPE = MediaType.parse("application/xml; charset=UTF-8"); private static final String CHARSET = "UTF-8"; private final XStream xStream; XStreamXmlRequestBodyConverter(XStream xStream) { this.xStream = xStream; } @Override public RequestBody convert(T value) throws IOException { Buffer buffer = new Buffer(); try { OutputStreamWriter osw = new OutputStreamWriter(buffer.outputStream(), CHARSET); xStream.toXML(value, osw); osw.flush(); } catch (Exception e) { throw new RuntimeException(e); } return RequestBody.create(MEDIA_TYPE, buffer.readByteString()); } }
So, this point we can send and receive any XML , We just need create XStream Annotations for the entities.
Then create a Retrofit instance:
XStream xs = new XStream(new DomDriver()); xs.autodetectAnnotations(true); Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://example.com/") .addConverterFactory(XStreamXmlConverterFactory.create(xs)) .client(client) .build();
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents