使用SimpleXMLConverterFactory进行Android Retrofit 2复杂对象映射

时间:2017-12-20 22:48:54

标签: android object mapping retrofit2

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

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

我似乎无法映射到Element(以及随后的兄弟姐妹,但为了简单起见):`

<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();
            }
        });
    }

1 个答案:

答案 0 :(得分: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类应该是'content'元素,但在Score类中,您声明的根元素是'properties'。我猜,一个注释只会覆盖另一个注释。

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

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