#How to use
dependencies {
//Add Retrofit dependencies
compile ('com.thoughtworks.xstream:xstream:1.4.7') {
exclude group: 'xmlpull', module: 'xmlpull'
}
}
import com.thoughtworks.xstream.XStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Converter;
import retrofit2.Retrofit;
/**
* Created by Anderson on 02/08/2016.
*
*/
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);
}
}
import com.thoughtworks.xstream.XStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okio.Buffer;
import retrofit2.Converter;
/**
* Created by Anderson on 02/08/2016.
*
*/
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());
}
}
import com.thoughtworks.xstream.XStream;
import java.io.IOException;
import okhttp3.ResponseBody;
import retrofit2.Converter;
/**
* Created by Anderson on 02/08/2016.
*
*/
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();
}
}
}
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("")
.addConverterFactory(XStreamXmlConverterFactory.create(new XStream(new DomDriver())))
.client(client)
.build();
Hi Anderson,
I have a question about your converter. At this moment i'm using Simple xml to convert Retrofit classes to xml documents. The only problem with Simple is that it can't handle self-closing xml tags. Now I was doing some research on alternatives for Simple and I found your comment here: https://futurestud.io/tutorials/retrofit-replace-the-integrated-json-converter . My question is: can i handle self-closing xml tags with your converter? I'm hoping for a quick response.