【问题标题】:Android Retrofit 2 complex object mapping using SimpleXMLConverterFactoryAndroid Retrofit 2 使用 SimpleXMLConverterFactory 的复杂对象映射
【发布时间】:2017-12-22 16:57:30
【问题描述】:

我的复杂 XML 结构 https://www.uj.ac.za/studyatUJ/_api/web/lists/getbytitle('aps_score_card')/items() 在这里美化了:https://codebeautify.org/xmlviewer

我已将我的 XML 映射对象添加到顶部的 ApsScoreCard 中,其中包含一个包含一个分数的 ContentScore 列表。 其中每一个都是上面提供的 XML 结构中的元素。

我似乎无法映射到元素(以及后续兄弟,但为了简单起见):`

<d:APS ...>some_value</d:APS>`

我不知道我的对象映射是错误还是其他错误,因为我似乎得到了正确的分数 = 10,但没有一个 d:APS 值。

public interface ProgrammeCourseClientApi {
   @GET("lists/getbytitle('aps_score_card')/items()")
   Call<ApsScoreCard> loadApsScoreCard();
}

public class ProgrammeCourseRetrofit  {

static final String BASE_URL = "https://www.uj.ac.za/studyatUJ/_api/web/";

public static ProgrammeCourseClientApi buildProgrammeCourseClient() {

    HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
    httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder.addInterceptor(httpLoggingInterceptor);

    Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(SimpleXmlConverterFactory.createNonStrict(
                    new Persister(
                            new AnnotationStrategy()
                    )
            ));

    Retrofit retrofit = retrofitBuilder
            .client(okHttpClientBuilder.build())
            .build();

    ProgrammeCourseClientApi clientApi = retrofit.create(ProgrammeCourseClientApi.class);

    return clientApi;
}
}


@Root(name = "m:properties", strict = false)
public class Score {
@Element(name = "d:APS", required = false)
private double mAps;

public void setAps(double vAps) {
    mAps = vAps;
}

public double getAps() {
    return mAps;
}

@Override
public String toString() {
    return "Score : " + getAps();
}

    public Score() {

    }
}

@Root(name = "entry", strict = false)
public class ContentScore {

    @Element(name = "content", required = false)
    private Score mScore;

    public void setScore(Score vScore) {
        mScore = vScore;
    }

    public Score getScore() {
        return mScore;
    }
}

@Root (name = "feed", strict = false)
public class ApsScoreCard {

    @ElementList (name = "entry", inline = true, required = false)
    private ArrayList<ContentScore> mScoreList = new ArrayList<>();

    public void setContentScoreList(ArrayList<ContentScore> vScoreList) {
        mScoreList = vScoreList;
    }

    public ArrayList<ContentScore> getContentScoreList() {
        return mScoreList;
    }

    @Override
    public String toString() {
        String list ="";
        for (int i = 0; i < getContentScoreList().size(); i++) {
            list += "\n" + getContentScoreList().get(i);
        }
        return list;
    }
}

public void loadRetrofitResults() {

        mProgrammeCourseClientApi = ProgrammeCourseRetrofit.buildProgrammeCourseClient();

        Call<ApsScoreCard> call = mProgrammeCourseClientApi.loadApsScoreCard();

        call.enqueue(new Callback<ApsScoreCard>() {
            @Override
            public void onResponse(Call<ApsScoreCard> call, Response<ApsScoreCard> response) {
                if(response.isSuccessful()) {
                    if(response.body().getContentScoreList() != null) {
                        ApsScoreCard apsScoreCard = response.body();
                        Score score = apsScoreCard.getContentScoreList().get(2).getScore();
                        mTempText.setText(Integer.toString(apsScoreCard.getContentScoreList().size()) +
                                ", Value(2) = " + score);
                    }
                } else {
                    Toast.makeText(getApplicationContext(), "Response is onsuksesvol", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<ApsScoreCard> call, Throwable t) {
                t.printStackTrace();
            }
        });
    }

【问题讨论】:

    标签: android object mapping retrofit2


    【解决方案1】:

    据我了解,您在创建带有注释的 POJO 类时遗漏了一点。 我尝试再添加一个类,现在您的项目运行良好!


        @Root(name = "feed", strict = false)
        public class ApsScoreCard {
    
            @ElementList(name = "entry", inline = true, required = false)
            private ArrayList<ContentScore> mScoreList = new ArrayList<>();
    
            public void setContentScoreList(ArrayList<ContentScore> vScoreList) {
                mScoreList = vScoreList;
            }
    
            public ArrayList<ContentScore> getContentScoreList() {
                return mScoreList;
            }
    
            @Override
            public String toString() {
                String list ="";
                for (int i = 0; i < getContentScoreList().size(); i++) {
                    list += "\n" + getContentScoreList().get(i);
                }
                return list;
            }
    
        public class ContentProperties {
            @Element(name = "properties", required = false)
            private Score mScore;
        }
    
    @Root(name = "entry", strict = false)
    public class ContentScore {
    
        @Element(name = "content", required = false)
        private ContentProperties mProperties;
        //private Score mScore;
    
        @Element(name = "updated", required = false)
        private String mUpdated;
    }
    
    public class Score {
        @Element(name = "Created", required = false)
        private String mCreated;
    
        @Element(name = "APS", required = false, type = Float.class)
        private float mAps;
    }
    

    在 ContentScore 类中,您定义 Score 类应该是“内容”元素,但在 Score 类中,您声明根元素是“属性”。我猜,一个注释会覆盖另一个注释。

    请注意,在新实现中,Score 类没有@Root 注释。

    如果您添加 ContentProperties 类,它应该可以解决问题。希望这会有所帮助

    【讨论】:

    • 谢谢。额外的课程修复了它。 XML 结构让我大吃一惊。
    猜你喜欢
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2014-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多