简体   繁体   English

改造-如何从JSON对象获取响应

[英]Retrofit - How to get response from JSON objects

I need to get a list of reviews using Retrofit from the following api query: 我需要从以下api查询中获取使用Retrofit的评论列表:

http://api.themoviedb.org/3/movie/{id}/reviews?api_key=#######

The JSON returned is: 返回的JSON是:

{"id":83542,"page":1,"results":[{"id":"51910979760ee320eb020fc2","author":"Andres Gomez","content":"Interesting film with an exceptional cast, fantastic performances and characterizations. The story, though, is a bit difficult to follow and, in the end, seems to not have a real point.","url":"https://www.themoviedb.org/review/51910979760ee320eb020fc2"},{"id":"520a8d10760ee32c8718e6c2","author":"Travis Bell","content":"Cloud Atlas was a very well made movie but unlike most of the \"simultaneous stories that all come together at the end\" type of movies, this one just didn't. I'm still unclear as to the point of it all.\r\n\r\nAnother issue I had was a general feeling of goofiness. Sure, the Cavendish story was pure comedy but the rest of the stories just didn't feel serious enough to me.\r\n\r\nIt carried my attention for the 172 minutes well enough and it was entertaining. I just expected more of a pay off at the end.\r\n\r\nAll in all, it's definitely worth seeing but I still haven't made up my mind if I truly liked it or not. What did you think?","url":"https://www.themoviedb.org/review/520a8d10760ee32c8718e6c2"}],"total_pages":1,"total_results":2}

My goal is to to access the "content" attribute and then put in a TextView. 我的目标是访问“内容”属性,然后放入TextView中。

Where I am having trouble is, for some reason I cannot figure out how to return a list of result objects from the above JSON and then access the content attribute using getContent(). 我遇到麻烦的地方,由于某种原因,我无法弄清楚如何从上述JSON返回结果对象列表,然后使用getContent()访问content属性。

I think there may be a problem with the way I am using my model object/s? 我认为我使用模型对象的方式可能存在问题? Should they be two seperate objects? 它们应该是两个单独的对象吗? I'm not sure. 我不确定。 When I try to print out the objects I get empty responses... 当我尝试打印对象时,我得到的响应是空的...

Any help would be great. 任何帮助都会很棒。

Retrofit interface code is: 改造接口代码为:

 public class MovieService {
    public interface MovieDbApi {

    @GET("/3/movie/{id}?&append_to_response=reviews")
    Call<MovieReview> getReviews(
            @Path("id") int id,
            @Query("api_key") String apiKey);

    }
}

Model object code is: 模型对象代码为:

POJO 1 POJO 1

public class MovieReview {

@SerializedName("id")
@Expose
private int id;
@SerializedName("page")
@Expose
private int page;

@SerializedName("results")
@Expose
private List<MovieReviewDetail> results = new ArrayList<MovieReviewDetail>();
@SerializedName("total_pages")
@Expose
private int totalPages;
@SerializedName("total_results")
@Expose
private int totalResults;

/**
 *
 * @return
 * The id
 */
public int getId() {
    return id;
}

/**
 *
 * @param id
 * The id
 */
public void setId(int id) {
    this.id = id;
}

/**
 *
 * @return
 * The page
 */
public int getPage() {
    return page;
}

/**
 *
 * @param page
 * The page
 */
public void setPage(int page) {
    this.page = page;
}

/**
 *
 * @return
 * The results
 */
public List<MovieReviewDetail> getResults() {
    return results;
}

/**
 *
 * @param results
 * The results
 */
public void setResults(List<MovieReviewDetail> results) {
    this.results = results;
}

/**
 *
 * @return
 * The totalPages
 */
public int getTotalPages() {
    return totalPages;
}

/**
 *
 * @param totalPages
 * The total_pages
 */
public void setTotalPages(int totalPages) {
    this.totalPages = totalPages;
}

/**
 *
 * @return
 * The totalResults
 */
public int getTotalResults() {
    return totalResults;
}

/**
 *
 * @param totalResults
 * The total_results
 */
public void setTotalResults(int totalResults) {
    this.totalResults = totalResults;
}

}

POJO 2 POJO 2

public class MovieReviewDetail {

@SerializedName("id")
@Expose
private int id;
@SerializedName("author")
@Expose
private String author;
@SerializedName("content")
@Expose
private String content;
@SerializedName("url")
@Expose
private String url;

/**
 *
 * @return
 * The id
 */
public int getId() {
    return id;
}

/**
 *
 * @param id
 * The id
 */
public void setId(int id) {
    this.id = id;
}

/**
 *
 * @return
 * The author
 */
public String getAuthor() {
    return author;
}

/**
 *
 * @param author
 * The author
 */
public void setAuthor(String author) {
    this.author = author;
}

/**
 *
 * @return
 * The content
 */
public String getContent() {
    return content;
}

/**
 *
 * @param content
 * The content
 */
public void setContent(String content) {
    this.content = content;
}

/**
 *
 * @return
 * The url
 */
public String getUrl() {
    return url;
}

/**
 *
 * @param url
 * The url
 */
public void setUrl(String url) {
    this.url = url;
}

}

Fragment code: 片段代码:

private static final String API_KEY = "#####";
private static final String API_BASE_URL_MOVIES = "http://api.themoviedb.org/";

private Call<MovieReview> call;
private MovieReview movieReview;
private List <MovieReviewDetail>  movieReviewDetails;

public void getMovieReview(int id){

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(API_BASE_URL_MOVIES)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    MovieService.MovieDbApi movieDbApi = retrofit.create(MovieService.MovieDbApi.class);

    call = movieDbApi.getReviews(id, API_KEY);

    call.enqueue(new Callback<MovieReview>() {
        @Override
        public void onResponse(Response<MovieReview> response) {
            if (!response.isSuccess()) {
                Log.d(LOG_TAG, "Error");
            }

            movieReview = response.body();
            movieReviewDetails = movieReview.getResults();

//Print out results 

for (int i = 0; i < movieReviewDetails.size(); i++) {
                System.out.println(movieReviewDetails.get(i).getContent());
            }

        }

        @Override
        public void onFailure(Throwable t) {

            Log.e("Throwable: ", t.getMessage());

        }
    });

}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);

    getMovieReview(83542);
}

I don't know why people type incorrect JSON response and then expect problems not to happen. 我不知道为什么人们输入不正确的JSON响应,然后期望问题不会发生。 Did you even bother to post the entire JSON response this is the response you get. 您是否还不愿意发布整个JSON响应,这就是您得到的响应。

{"adult":false,"backdrop_path":"/2ZA03KiD4jePTNBTJjGGFTNQPMA.jpg","belongs_to_collection":null,"budget":102000000,"genres":[{"id":18,"name":"Drama"},{"id":878,"name":"Science Fiction"}],"homepage":"http://cloudatlas.warnerbros.com/","id":83542,"imdb_id":"tt1371111","original_language":"en","original_title":"Cloud Atlas","overview":"A set of six nested stories spanning time between the 19th century and a distant post-apocalyptic future. Cloud Atlas explores how the actions and consequences of individual lives impact one another throughout the past, the present and the future. Action, mystery and romance weave through the story as one soul is shaped from a killer into a hero and a single act of kindness ripples across centuries to inspire a revolution in the distant future.  Based on the award winning novel by David Mitchell. Directed by Tom Tykwer and the Wachowskis.","popularity":3.552761,"poster_path":"/8VNiyIp67ZxhpNgdrwACW0jgvP2.jpg","production_companies":[{"name":"Anarchos Productions","id":450},{"name":"X-Filme Creative Pool","id":1972},{"name":"Ascension Pictures","id":7829},{"name":"ARD Degeto Film","id":10947},{"name":"Cloud Atlas Productions","id":11080},{"name":"Five Drops","id":11082},{"name":"Media Asia Group","id":11083},{"name":"Dreams of Dragon Picture","id":19621}],"production_countries":[{"iso_3166_1":"DE","name":"Germany"},{"iso_3166_1":"HK","name":"Hong Kong"},{"iso_3166_1":"SG","name":"Singapore"},{"iso_3166_1":"US","name":"United States of America"}],"release_date":"2012-10-26","revenue":130482868,"runtime":172,"spoken_languages":[{"iso_639_1":"en","name":"English"}],"status":"Released","tagline":"Everything is Connected","title":"Cloud Atlas","video":false,"vote_average":6.4,"vote_count":1774,"reviews":{"page":1,"results":[{"id":"51910979760ee320eb020fc2","author":"Andres Gomez","content":"Interesting film with an exceptional cast, fantastic performances and characterizations. The story, though, is a bit difficult to follow and, in the end, seems to not have a real point.","url":"https://www.themoviedb.org/review/51910979760ee320eb020fc2"},{"id":"520a8d10760ee32c8718e6c2","author":"Travis Bell","content":"Cloud Atlas was a very well made movie but unlike most of the \"simultaneous stories that all come together at the end\" type of movies, this one just didn't. I'm still unclear as to the point of it all.\r\n\r\nAnother issue I had was a general feeling of goofiness. Sure, the Cavendish story was pure comedy but the rest of the stories just didn't feel serious enough to me.\r\n\r\nIt carried my attention for the 172 minutes well enough and it was entertaining. I just expected more of a pay off at the end.\r\n\r\nAll in all, it's definitely worth seeing but I still haven't made up my mind if I truly liked it or not. What did you think?","url":"https://www.themoviedb.org/review/520a8d10760ee32c8718e6c2"}],"total_pages":1,"total_results":2}}

Notice the fact that that you can't directly access the inner object. 请注意,您不能直接访问内部对象。 Your outer object is reviews . 您的外部对象是评论 You must then create a POJO class depicting that. 然后,您必须创建一个描述它的POJO类。

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

/**
 * Created by Ramandeep Singh on 17-03-2016.
 */
public class Reviews {
    @SerializedName("reviews")
    @Expose
private MovieReview reviews;

    public Reviews() {
    }


    public MovieReview getReviews() {
        return reviews;
    }

    public void setReviews(MovieReview reviews) {
        this.reviews = reviews;
    }
}

And furthermore, the ID is not Integer, it is string field. 而且, ID不是整数,而是字符串字段。

Next time onwards type the correct and whole JSON response. 下次再输入正确且完整的JSON响应。

This is the method. 这就是方法。 After modification to service and utility 修改服务和实用程序之后

 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_BASE_URL_MOVIES)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        MovieService.MovieDbApi movieDbApi = retrofit.create(MovieService.MovieDbApi.class);

        call = movieDbApi.getReviews(id, API_KEY);

        call.enqueue(new Callback<Reviews>() {
                         @Override
                         public void onResponse(Call<Reviews> call, Response<Reviews> response) {
                             if (!response.isSuccessful()) {
                                 System.out.println("Error");
                             }

                             reviews = response.body();
                             movieReview=reviews.getReviews();
                             movieReviewDetails = movieReview.getResults();

//Print out results

                             for (int i = 0; i < movieReviewDetails.size(); i++) {
                                 System.out.println(movieReviewDetails.get(i).getContent());
                             }

                         }

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

                         }
                     }
      );

This is your service now. 这是您的服务。

import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;

/**
 * Created by Ramandeep Singh on 17-03-2016.
 */
public class MovieService {
    public interface MovieDbApi {

        @GET("/3/movie/{id}?&append_to_response=reviews")
        Call<Reviews> getReviews(
                @Path("id") int id,
                @Query("api_key") String apiKey);

    }
}

This is the output you get. 这是您得到的输出。

Interesting film with an exceptional cast, fantastic performances and characterizations. The story, though, is a bit difficult to follow and, in the end, seems to not have a real point.
Cloud Atlas was a very well made movie but unlike most of the "simultaneous stories that all come together at the end" type of movies, this one just didn't. I'm still unclear as to the point of it all.

Another issue I had was a general feeling of goofiness. Sure, the Cavendish story was pure comedy but the rest of the stories just didn't feel serious enough to me.

It carried my attention for the 172 minutes well enough and it was entertaining. I just expected more of a pay off at the end.

All in all, it's definitely worth seeing but I still haven't made up my mind if I truly liked it or not. What did you think?

Give this a try, Instead of seperating get call and get call with enqueue. 尝试一下,而不是将get call和enqueue分开。

call = movieDbApi.getReviews(id, API_KEY).enqueue(new Callback<MovieReview>() {
        @Override
        public void onResponse(Response<MovieReview> response) {
            if (!response.isSuccess()) {
                Log.d(LOG_TAG, "Error");
            }

            movieReview = response.body();
            movieReviewDetails = movieReview.getResults();

//Print out results 

for (int i = 0; i < movieReviewDetails.size(); i++) {
                System.out.println(movieReviewDetails.get(i).getContent());
            }

        }

        @Override
        public void onFailure(Throwable t) {

            Log.e("Throwable: ", t.getMessage());

        }
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM