改造 2 自定義 Xml 轉換器
將依賴項新增到 build.gradle 檔案中。
dependencies {
....
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile ('com.thoughtworks.xstream:xstream:1.4.7') {
exclude group: 'xmlpull', module: 'xmlpull'
}
....
}
然後建立 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);
}
}
建立一個類來處理 body 請求。
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();
}
}
}
建立一個類來處理身體反應。
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());
}
}
所以,這一點我們可以傳送和接收任何 XML,我們只需要為實體建立 XStream Annotations。
然後建立一個 Retrofit 例項:
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();