我在xml中有一个服务器响应,格式不正确且没有根元素:
<option value="stationAValue">stationADescription</option>
<option value="stationBValue">stationBDescription</option>
我试图像这样使用SimpleXmlConverterFactory
:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Params.BASE_URL)
.client(okHttpClient)
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
这是我的代表一行的类:
public class Station {
@Element(name = "option")
private String mName;
@Attribute(required = false)
private String value;
}
但当然不能在没有根元素的情况下解析它,
有没有办法在SimpleXmlConverterFactory
尝试解析响应之前操纵响应,并添加根元素?
或许是另一种解决方案?
答案 0 :(得分:3)
使用Retrofit / OkHttp,您有2个拦截这些请求的选项:
两者都有点装饰模式。
直接将响应修改为http堆栈的一部分:
public class XmlInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response response = chain.proceed(chain.request());
ResponseBody body = response.body();
String wrappedBody = "<root>" + body.string() + "</root>";
return response.newBuilder()
.body(ResponseBody.create(body.contentType(), wrappedBody))
.build();
}
}
只需将拦截器添加到OkHttp
即可new OkHttpClient.Builder()
.addInterceptor(new XmlInterceptor())
.build();
包装您要使用的解析器,然后再次修改响应。这里的好处是,您可以为包装添加自定义注释。例如传入根元素的名称。
public class XmlParser extends Converter.Factory {
private Converter.Factory factory = SimpleXmlConverterFactory.create();
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
// here you can actually look at the annotations, type, etc.
return new WrappedResponseBodyConverter(factory.responseBodyConverter(type, annotations, retrofit));
}
private class WrappedResponseBodyConverter<T> implements Converter<ResponseBody, T> {
private Converter<ResponseBody, T> responseBodyConverter;
public WrappedResponseBodyConverter(Converter<ResponseBody, T> responseBodyConverter) {
this.responseBodyConverter = responseBodyConverter;
}
@Override
public T convert(ResponseBody value) throws IOException {
String body = "<root>" + value.string() + "</root>";
ResponseBody wrapped = ResponseBody.create(value.contentType(), body);
return responseBodyConverter.convert(value);
}
}
}
然后使用这个。
new Retrofit.Builder()
.addConverterFactory(new XmlParser())
.build();
选择您喜欢的任何一种,因为没有正确或错误的imho。
代码未经过测试。这只是一个例子。
答案 1 :(得分:-1)
I have done something almost similar to your current ptoblem. Once you receive the xml response in java, you can use + operation to include you root element, like so :
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<root>" + response + "</root>";
here, response is the xml response you get you get in String format. Note that you can also manipulate the xml respose to suit your needs by treating it as a string, so you can concat any additional data into your response and you can also split the response at different parts to suit the format that you require. Hope this will assist.