通常,每个响应都是这样的(当然,< response>标记中包含的实际元素随每个请求而变化):
<?xml version="1.0" enCoding="UTF-8"?><response> <SomeInfo>Some Info</SomeInfo> <MoreInfo>More Info</MoreInfo></response>
每个错误都是这样的(这里的结构对于每个响应都是相同的):
<?xml version="1.0" enCoding="UTF-8"?><error> <code>125002</code> <message></message></error>
现在,到目前为止我们发现的唯一方法是以一种通用的方式完成这项工作,如下所示:
public interface API { @GET("/API/sessionToken") Observable<ResponseBody> requestSessionToken(); @GET("/API/pinStatus") Observable<ResponseBody> requestPinStatus();}public class RestClIEnt { public RestClIEnt() { // ... mAPIService = retrofit.create(API.class); } public Observable<PinStatusResponse> requestPinStatus() { return mAPIService.requestPinStatus() .flatMap(foo(PinStatusResponse.class,PinStatusResponseData.class)); } public Observable<SessionTokenResponse> requestSessionToken() { return mAPIService.requestSessionToken() .flatMap(foo(SessionTokenResponse.class,SessionTokenResponseData.class)); } private final <O extends MyResponse,I> Func1<ResponseBody,Observable<T>> foo(final Class<O> outerCls,final Class<I> innerCls) { return new Func1<ResponseBody,Observable<O>>() { @OverrIDe public Observable<O> 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((O) outerCls.getConstructor(MyError.class,innerCls).newInstance(myError,null)); } else if (TextUtils.equals(roottag,"response")) { final I data = serializer.read(innerCls,xmlString); return Observable.just((T) outerCls.getConstructor(MyError.class,innerCls).newInstance(null,data)); } } catch (XmlPullParserException e) { return Observable.error(e); } catch (IOException e) { return Observable.error(e); } catch (Exception e) { return Observable.error(e); } return Observable.error(new Exception("Should not be reached...")); } }; }}
Response类看起来像这样:
public abstract class MyResponse<T> { public final MyError error; public final T data; protected MyResponse(MyError error,T data) { this.error = error; this.data = data; }}
和:
public final class PinStatusResponse extends MyResponse<PinStatusResponseData> { public PinStatusResponse(MyError error,PinStatusResponseData data) { super(error,data); }}
并且所有* Data类都直接对应于(非错误)XML响应.
现在,我的问题是:有没有更简单的方法来解决这个问题? (如果是这样,这是不良API设计的标志吗?).
解决方法 这就是@ElementUnion注释的用途.您可以通过使用带注释的对象使用纯Retrofit SimpleXML API来解决这个问题:@Rootpublic class ResponseBody { public interface IAPIResponse { } @Root public static class ValIDResponse implements IAPIResponse { @Element(name="SomeInfo") String someInfo; @Element(name="MoreInfo") String moreInfo; } @Root public static class ErrorResponse implements IAPIResponse { @Element(name="code") int code; @Element(name="message") String message; } @ElementUnion({ @Element(name="response",type=ValIDResponse.class),@Element(name="error",type=ErrorResponse.class) }) IAPIResponse APIResponse;}
*’ValIDResponse’和’ErrorReponse’的具体结构必须根据您拥有的真实XML结构进行更改.您可能还希望考虑在他们的@Root中添加’strict = false’.
至于你的’API’界面,它必须看起来像这样(注意我在使用Retrofit的Call类时):
public interface API { @GET("/API/sessionToken") Call<ResponseBody> requestSessionToken(); @GET("/API/pinStatus") Call<ResponseBody> requestPinStatus();}
最后,调用本身(例如requestPinStatus())应该根据这个骨架实现来解决:
Call<ResponseBody> result = mAPIService.requestPinStatus();result.enqueue(new Callback<ResponseBody>() { @OverrIDe public voID onResponse(Response<ResponseBody> response,Retrofit retrofit) { // ... if (response.body().APIResponse instanceof ValIDResponse) { // ... } else if (response.body().APIResponse instanceof ErrorResponse) { // ... } } @OverrIDe public voID onFailure(Throwable t) { // ... }});
有关ElementUnion和Simple-XML注释的更多信息,请参阅this guide.
总结以上是内存溢出为你收集整理的android – 用于未知根元素的Retrofit和SimpleXML?全部内容,希望文章能够帮你解决android – 用于未知根元素的Retrofit和SimpleXML?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)