Мы работаем над проектом Android с XML API, используя RxJava
, Retrofit
и SimpleXML
для обработки запросов и ответов. Корень из ответов может варьироваться beteween двух типов:SimpleXML and Retrofit: модель для ответа только с корневым элементом
<?xml version="1.0" encoding="UTF-8"?>
<response>
<Element1>Integer</Element1>
<Element2>Integer</Element2>
...
</response>
или
<?xml version="1.0" encoding="UTF-8"?>
<error>
<Element1>String</Element1>
<Element2>Integer</Element2>
</error>
Поэтому мы используем XMLPullParse для анализа различных видов ответов на различные модели с сопровождающими их элементами, который работает отлично.
MyResponse: супер класс, который сочетает в себе возможно errors
и valid
ответы:
public abstract class MyResponse<T> {
public final MyError error;
public final T data;
protected MyResponse(MyError mError, T data) {
this.error = mError;
this.data = data;
}
public final boolean isError() {
return error != null;
}
@Override
public String toString() {
return "MyResponse{" +
"error=" + error +
", data=" + data +
'}';
}
public T getData() {
return data;
}
}
SessionTokenResponse: Пример для response
класса, который простирается MyResponse
public class SessionTokenResponse extends MyResponse<SessionTokenResponseData>{
public SessionTokenResponse(MyError mError, SessionTokenResponseData response) {
super(mError, response);
}
}
SessionTokenResponseData: Экземпляр ле класс, показывающий, как мы построить модель
@Root(name = "data")
public class SessionTokenResponseData {
@Element(name = "Session")
private String sessionInfo;
@Element(name = "Token")
private String tokenInfo;
public String getSessionInfo() {
return sessionInfo;
}
....
}
RestClient - Foo(): метод в нашем классе RestClient разобрать различные виды ответов. Если она была успешной, то ответ будет <response>
как корневой элемент, если не корневой элемент будет иметь тип <error>
private final <T extends MyResponse, I> Func1<ResponseBody, Observable<T>> foo(final Class<T> cls, final Class<I> innerCls) {
return new Func1<ResponseBody, Observable<T>>() {
@Override
public Observable<T> call(ResponseBody responseBody) {
try {
final String xmlString = responseBody.string();
final XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(new ByteArrayInputStream(xmlString.getBytes(Charset.forName("UTF-8"))), null);
parser.nextTag();
final String rootTag = parser.getName();
final Serializer serializer = new Persister();
if (TextUtils.equals(rootTag, "error")) {
final MyError myError = serializer.read(MyError.class, xmlString);
return Observable.just((T) cls.getConstructor(MyError.class, innerCls).newInstance(myError, null));
} else if (TextUtils.equals(rootTag, "response")) {
final I data = serializer.read(innerCls, xmlString);
return Observable.just((T) cls.getConstructor(HuiError.class, innerCls).newInstance(null, data));
}
Но у нас есть проблемы с одним типом ответа, который выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<response>
OK
</response>
Наш вопрос: Как мы можем построить модель для такого ответа, если у нее нет элементов? Нам по-прежнему необходимо различать другие ответы с помощью корня <response>
.