我们正在开发一个带有XML API的Android项目,使用RxJava
,Retrofit
和SimpleXML
来处理请求和响应。响应的根源可以在两种类型之间变化:
<?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 :扩展MyResponse的response
类示例
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>
根的其他响应。
答案 0 :(得分:1)
在一个自发的想法之后,我们自己找到了答案。 响应将扩展超类,并且不会包含任何其他模型类,例如我的示例类 SessionTokenResponseData ,但只包含字符串:
public class LoginResponse extends MyResponse<String>{
public LoginResponse(MyError mError, String response) {
super(mError, response);
}
}
所以我们不需要在RestClient类方法中修改我们的手动解析,它工作正常。