我使用Retrofit作为REST客户端并获得以下响应:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"Response":{"Status":"success","Response........... </string>
如果可能的话,我如何让Retrofit开始在xml
标签之后解析对象,如果没有,还有其他解决方案吗?
答案 0 :(得分:2)
这很简单。据我所知,Retrofit不提供转换器链,但你仍然可以包装多个转换器:
final class XmlWrappedConverterFactory
extends Converter.Factory {
// This is the converter factory the deserialization will be delegated to
private final Converter.Factory backingConverterFactory;
private XmlWrappedConverterFactory(final Converter.Factory backingConverterFactory) {
this.backingConverterFactory = backingConverterFactory;
}
static Converter.Factory create(final Converter.Factory backingConverterFactory) {
return new XmlWrappedConverterFactory(backingConverterFactory);
}
@Override
public Converter<ResponseBody, ?> responseBodyConverter(final Type type, final Annotation[] annotations, final Retrofit retrofit) {
final Converter<ResponseBody, ?> responseBodyConverter = backingConverterFactory.responseBodyConverter(type, annotations, retrofit);
return new XmlWrappedResponseBodyConverter(responseBodyConverter);
}
private static final class XmlWrappedResponseBodyConverter
implements Converter<ResponseBody, Object> {
private final Converter<ResponseBody, ?> responseBodyConverter;
private XmlWrappedResponseBodyConverter(final Converter<ResponseBody, ?> responseBodyConverter) {
this.responseBodyConverter = responseBodyConverter;
}
@Override
public Object convert(final ResponseBody responseBody)
throws IOException {
// Note the response is not converted to string in order to save memory and work in streaming fashion
// So just fast-forward until '>' is found -- let's pretend it's an XML pretty much then
fastForward(responseBody.charStream(), '>');
// GsonConverterFactory uses charStream() as well, at this step the stream will be "fast-forwarded"
return responseBodyConverter.convert(responseBody);
// However, the GsonConverterFactory closes the charStream() so wer're unable to read it until the end -- not that bad in fact
}
private static void fastForward(final Reader reader, final char ch)
throws IOException {
// Just read until the given character is found or EOF
int read;
while ( (read = reader.read()) != ch && read != -1 ) {
}
}
}
}
然后构建Retrofit
实例很简单:
final Retrofit retrofit = new Builder()
...
.addConverterFactory(XmlWrappedConverterFactory.create(GsonConverterFactory.create()))
.build();
答案 1 :(得分:1)
您必须编写自定义Converter。
这样的事情:
new Retrofit.Builder()
.baseUrl(...)
.addCallAdapterFactory(...)
.addConverterFactory(new Converter.Factory() {
@Override
public Converter<ResponseBody, YourModel> responseBodyConverter(final Type type,
final Annotation[] annotations, final Retrofit retrofit) {
return new Converter<ResponseBody, YourModel>() {
@Override
public YourModel convert(final ResponseBody value) throws IOException {
String responseString = value.string();
int startIndex = responseString.indexOf(">");
++startIndex;
int endIndex = responseString.indexOf("<", 1);
String jsonResponse = responseString.substring(startIndex, endIndex);
YourModel yourModel = new Gson().fromJson(jsonResponse, YourModel.class);
return yourModel;
}
};
}
})
.build()
.create(...);
注意,这只是一个草图,它可能无法正常运行,我还没有测试过。让我知道我是否应该编辑它。