Retrofit从json键返回null值,尽管它具有响应android

时间:2019-07-03 03:28:58

标签: android android-studio retrofit android-livedata

我有这样的json响应。

SELECT u.id 
FROM users u
LEFT JOIN relationships r ON r.target_user_id = u.id
    AND r.user_id = 1
WHERE u.is_active=1 AND r.target_user_id IS NULL

在上面的json响应中,您可以看到“ Poster” json键在第一个数据集中不存在,而在第二个数据集中存在,类似地,它为null。

现在的问题是,当我在翻新中使用时,仅返回Poster中的一个数据,而返回,而对于其他所有数据,它显示为 null 。问题仅针对Poster

下面是我上课的方法。

{
  "movies": [
    {
      "Title": "Avengers:Age of Ultron ",
      "Year": "2015 ",
      "Rated": "PG-13 ",
      "Released": "01 May 2015 ",
      "Runtime": "141 min ",
      "Genre": "Action, Adventure, Sci-Fi ",
      "Director": "Joss Whedon ",
      "Writer": "Joss Whedon, Stan Lee (based on the Marvel comics by), Jack Kirby (based on the Marvel comics by), Joe Simon (character created by: Captain America), Jack Kirby (character created by: Captain America), Jim Starlin (character created by: Thanos) ",
      "Actors": "Robert Downey Jr., Chris Hemsworth, Mark Ruffalo, Chris Evans ",
      "Plot": "When Tony Stark and Bruce Banner try to jump-start a dormant peacekeeping program called Ultron, things go horribly wrong and it's up to Earth's mightiest heroes to stop the villainous Ultron from enacting his terrible plan. ",
      "Language": "English, Korean ",
      "Country": "USA ",
      "Awards": "7 wins \u0026 45 nominations."
    },
    {
      "Title": "TheAvengers ",
      "Year": "2012 ",
      "Rated": "PG-13 ",
      "Genre": "Action, Adventure, Sci-Fi ",
      "Actors": "Robert Downey Jr., Chris Evans, Mark Ruffalo, Chris Hemsworth ",
      "Plot": "Earth's mightiest heroes must come together and learn to fight as a team if they are going to stop the mischievous Loki and his alien army from enslaving humanity. ",
      "Language": "English, Russian, Hindi ",
      "Country": "USA ",
      **"Poster": "https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300.jpg ",**
      "Released": "04 May 2012 ",
      "Runtime": "143 min ",
      "Director": "Joss Whedon ",
      "Writer": "Joss Whedon (screenplay), Zak Penn (story), Joss Whedon (story) ",
      "Awards": "Nominated for 1 Oscar. Another 38 wins \u0026 79 nominations. "
    },
    {
      "Title": "Sleepless ",
      "Year": "2017 ",
      "Rated": "R ",
      "Released": "13Jan 2017 ",
      "Runtime": "95 min ",
      "Genre": "Action, Crime, Thriller ",
      "Director": "Baran bo Odar ",
      "Writer": "Andrea Berloff (screenplay by), Frédéric Jardin (based on the film    Nuit blanche written by), Nicolas Saada (based on the film Nuit blanche written by), Olivier Douyère (based on the film    Nuit blanche   written by)",
      "Actors": "Jamie Foxx, Michelle Monaghan, Scoot McNairy, Dermot Mulroney ",
      "Plot": "A cop with a connection to the criminal underworld scours a nightclub in search of his kidnapped son. ",
      "Language": "English ",
      "Country": "USA ",
      "Awards": "1 nomination. ",
      **"Poster ": "https://m.media-amazon.com/images/M/MV5BNjEwMDAyOTM4OV5BMl5BanBnXkFtZTgwMzc4MjMyMDI@._V1_SX300.jpg "**
    },
    {
      "Title": "TheDark Knight ",
      "Year": "2008 ",
      "Rated": "PG-13 ",
      "Released": "18 Jul 2008 ",
      "Runtime": "152 min ",
      "Genre": "Action, Crime, Drama ",
      "Director": "Christopher Nolan ",
      "Writer": "Jonathan Nolan (screenplay), Christopher Nolan (screenplay), Christopher Nolan (story), David S. Goyer (story), Bob Kane (characters) ",
      "Actors": "Christian Bale, Heath Ledger, Aaron Eckhart, Michael Caine ",
      "Plot": "When the menace known as the Joker emerges from his mysterious past, he wreaks havoc and chaos on the people of Gotham. The Dark Knight must accept one of the greatest psychological and physical tests of his ability to fight injustice. ",
      "Language": "English, Mandarin ",
      "Country": "USA, UK ",
      "Awards": "Won 2 Oscars. Another 152 wins \u0026 155 nominations. ",
      **"Poster ": "https://m.media-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_SX300.jpg "**
    },
    {
      "Title": "SavingPrivate Ryan ",
      "Year": "1998 ",
      "Rated": "R ",
      "Released": "24 Jul 1998 ",
      "Runtime": "169 min ",
      "Genre": "Drama, War ",
      "Director": "Steven Spielberg ",
      "Writer": "Robert Rodat ",
      "Actors": "Tom Hanks, Tom Sizemore, Edward Burns, Barry Pepper ",
      "Plot": "Following the Normandy Landings, a group of U.S. soldiers go behind enemy lines to retrieve a paratrooper whose brothers have been killed in action. ",
      "Language": "English, French, German, Czech ",
      "Country": "USA ",
      "Awards": "Won 5 Oscars. Another 74 wins \u0026 74 nominations. ",
      **"Poster ": "https://m.media-amazon.com/images/M/MV5BZjhkMDM4MWItZTVjOC00ZDRhLThmYTAtM2I5NzBmNmNlMzI1XkEyXkFqcGdeQXVyNDYyMDk5MTU@._V1_SX300.jpg "**
    },
    {
      "Plot": "Moirac, a notary, and Landron, a retired army surgeon, who have been friends since boyhood, live in the same village. The daughter of the notary is, at the same time, the god-child of the...",
      "Title": "Fatherand God Father ",
      "Year": "1912 ",
      "Rated": "N/A ",
      "Released": "27 Feb 1913 ",
      "Runtime": "N/A ",
      "Genre": "Short, Comedy ",
      "Director": "N/A ",
      "Writer": "N/A ",
      "Actors": "N/A ",
      "Language": "French ",
      "Country": "France ",
      "Awards": "N/A ",
      **"Poster ": "N/A ",**
      "Ratings ": "",
      "Metascore ": "N/A ",
      "imdbRating ": "N/A ",
      "imdbVotes ": "N/A ",
      "imdbID ": "tt1318958 ",
      "Type ": "movie ",
      "DVD ": "N/A ",
      "BoxOffice ": "N/A ",
      "Production ": "N/A ",
      "Website ": "N/A ",
      "Response ": "True "
    }

上面是pojo类,我在其中将其指定为发帖人的SerializedName。

现在进行翻新,

public class Movies {
    @SerializedName("Released")
    private String Released;
    @SerializedName("Plot")
    private String Plot;
    @SerializedName("Director")
    private String Director;
    @SerializedName("Title")
    private String Title;
    @SerializedName("Actors")
    private String Actors;
    @SerializedName("Runtime")
    private String Runtime;
    @SerializedName("Awards")
    private String Awards;
    @SerializedName("Year")
    private String Year;
    @SerializedName("Language")
    private String Language;
    @SerializedName("Rated")
    private String Rated;
    @SerializedName("Country")
    private String Country;
    @SerializedName("Genre")
    private String Genre;
    @SerializedName("Writer")
    private String Writer;
    @SerializedName("Poster")
    @Expose
    private String Poster;

    public String getPoster() {
        return Poster;
    }

    public void setPoster(String Poster) {
        this.Poster = Poster;
    }

    public String getReleased() {
        return Released;
    }

    public void setReleased(String Released) {
        this.Released = Released;
    }

    public String getPlot() {
        return Plot;
    }

    public void setPlot(String Plot) {
        this.Plot = Plot;
    }

    public String getDirector() {
        return Director;
    }

    public void setDirector(String Director) {
        this.Director = Director;
    }

    public String getTitle() {
        return Title;
    }

    public void setTitle(String Title) {
        this.Title = Title;
    }

    public String getActors() {
        return Actors;
    }

    public void setActors(String Actors) {
        this.Actors = Actors;
    }

    public String getRuntime() {
        return Runtime;
    }

    public void setRuntime(String Runtime) {
        this.Runtime = Runtime;
    }

    public String getAwards() {
        return Awards;
    }

    public void setAwards(String Awards) {
        this.Awards = Awards;
    }

    public String getYear() {
        return Year;
    }

    public void setYear(String Year) {
        this.Year = Year;
    }

    public String getLanguage() {
        return Language;
    }

    public void setLanguage(String Language) {
        this.Language = Language;
    }

    public String getRated() {
        return Rated;
    }

    public void setRated(String Rated) {
        this.Rated = Rated;
    }

    public String getCountry() {
        return Country;
    }

    public void setCountry(String Country) {
        this.Country = Country;
    }

    public String getGenre() {
        return Genre;
    }

    public void setGenre(String Genre) {
        this.Genre = Genre;
    }

    public String getWriter() {
        return Writer;
    }

    public void setWriter(String Writer) {
        this.Writer = Writer;
    }

在这里,当我看到时,我得到的是第一个数据,但所有其他响应,海报都为空。

当我调试并检查时,(我没有完全张贴。我只拍了海报)

public class MoviesRepository {
    private static MoviesRepository moviesRepository;
    private MovieApiInterface newsApi;
    public static Application application;

    public static MoviesRepository getInstance() {
        if (moviesRepository == null) {
            moviesRepository = new MoviesRepository(application);
        }
        return moviesRepository;
    }



    public MoviesRepository(Application application) {
        this.application = application;
        newsApi = RetrofitService.cteateService(MovieApiInterface.class);
    }

public MutableLiveData<MovieResponse> getMovieUpdates() {
    final MutableLiveData<MovieResponse> moviesData = new MutableLiveData<>();
    newsApi.getMovieDetails().enqueue(new Callback<MovieResponse>() {
        @Override
        public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
            if (response.isSuccessful()) {
                if(response.body()!=null) {
                    moviesData.setValue(response.body());
                }
            }

        }

        @Override
        public void onFailure(Call<MovieResponse> call, Throwable t) {
            Log.i("RETROFIT RESPONSE", "Failure"+call.toString());
            Log.i("RETROFIT RESPONSE", "Failure"+t);
           // moviesData.setValue(null);

        }
    });
    return moviesData;
}
当我检查响应时,除了位置1 以外,所有

海报本身都为空。

MoviesResponse:

position 1:
Poster = "https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300.jpg "
    position 2:
    Poster = null
    position 3: 
    Poster = null

MoviesViewModel:

 public class MovieResponse implements Serializable {
    @SerializedName("movies")
    private List<Movies> movies;

    public List<Movies> getMovies() {
        return movies;
    }

    public void setMovies(List<Movies> movies) {
        this.movies = movies;
    }
}

RetrofitService:

 public class MoviesViewModel extends AndroidViewModel {
    private MutableLiveData<MovieResponse> mutableLiveData;
    private MoviesRepository moviesRepository;

    public MoviesViewModel(@NonNull Application application) {
        super(application);
        moviesRepository = new MoviesRepository(application);
    }

    public void init() {
        if (mutableLiveData != null) {
            return;
        }
        moviesRepository = MoviesRepository.getInstance();
        mutableLiveData = moviesRepository.getMovieUpdates();
    }

    public MutableLiveData<MovieResponse> getNewsRepository() {
        return moviesRepository.getMovieUpdates();
    }
}

MainActivity:

public class RetrofitService {
    private static Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("https://api.myjson.com/bins/")
            .addConverterFactory(GsonConverterFactory.create())
            .build();


    public static <S> S cteateService(Class<S> serviceClass) {
        return retrofit.create(serviceClass);
    }
}



public class MoviesRepository {
    private static MoviesRepository moviesRepository;
    private MovieApiInterface newsApi;
    public static Application application;

    public static MoviesRepository getInstance() {
        if (moviesRepository == null) {
            moviesRepository = new MoviesRepository(application);
        }
        return moviesRepository;
    }



    public MoviesRepository(Application application) {
        this.application = application;
        newsApi = RetrofitService.cteateService(MovieApiInterface.class);
    }

    public MutableLiveData<MovieResponse> getMovieUpdates() {
        final MutableLiveData<MovieResponse> moviesData = new MutableLiveData<>();
        newsApi.getMovieDetails().enqueue(new Callback<MovieResponse>() {
            @Override
            public void onResponse(Call<MovieResponse> call, Response<MovieResponse> response) {
                if (response.isSuccessful()) {
                    if(response.body()!=null) {
                        moviesData.setValue(response.body());
                    }
                }

            }

            @Override
            public void onFailure(Call<MovieResponse> call, Throwable t) {
                Log.i("RETROFIT RESPONSE", "Failure"+call.toString());
                Log.i("RETROFIT RESPONSE", "Failure"+t);
               // moviesData.setValue(null);

            }
        });
        return moviesData;
    }
}

MoviesAdapter:

public class MainActivity extends AppCompatActivity {
    MoviesAdapter newsAdapter;
    RecyclerView rvHeadline;
    MoviesViewModel newsViewModel;
    List<Movies> newsArticles;
    List<Movies> articleArrayList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rvHeadline = findViewById(R.id.rvNews);
         articleArrayList = new ArrayList<>();

        newsAdapter = new MoviesAdapter(MainActivity.this, articleArrayList);
        rvHeadline.setLayoutManager(new LinearLayoutManager(this));
        rvHeadline.setAdapter(newsAdapter);

        newsViewModel = ViewModelProviders.of(this).get(MoviesViewModel.class);
        newsViewModel.init();
        newsViewModel.getNewsRepository().observe(this, newsResponse -> {

            if (newsResponse != null) {
                newsArticles = newsResponse.getMovies();
                articleArrayList.addAll(newsArticles);
                for(int i=0;i<articleArrayList.size();i++){
                    String poster = articleArrayList.get(i).getPoster();
                    Log.i("poster","poster"+poster);
                }
                newsAdapter.notifyDataSetChanged();
            }
        });
       // setupRecyclerView();
    }

    private void setupRecyclerView() {
        if (newsAdapter == null) {
            newsAdapter = new MoviesAdapter(MainActivity.this, articleArrayList);
            rvHeadline.setLayoutManager(new LinearLayoutManager(this));
            rvHeadline.setAdapter(newsAdapter);
            rvHeadline.setItemAnimator(new DefaultItemAnimator());
            rvHeadline.setNestedScrollingEnabled(true);
        } else {
            newsAdapter.notifyDataSetChanged();
        }
    }
}

3 个答案:

答案 0 :(得分:0)

我认为您的某些响应对象没有该Poster键,例如示例代码段中的第一个对象。

答案 1 :(得分:0)

您可以通过返回默认的空白字符串或默认的URL来处理它。参见下面的示例。

在模型课程中,您必须这样做。

@Expose
@SerializedName("Poster")
private String Poster;

public String getPoster() {
   return Poster == null ? "https://m.media-amazon.com/images/M/MV5BNDYxNjQyMjAtNTdiOS00NGYwLWFmNTAtNThmYjU5ZGI2YTI1XkEyXkFqcGdeQXVyMTMxODk2OTU@._V1_SX300.jpg" : Poster;
}

public void setPoster(String Poster) {
   this.Poster = Poster;
}

在上面的代码中,如果在json中找不到您的发布者密钥,则可以返回“”或默认URL 。如果在那时找到了Poster键,它将返回其值。

答案 2 :(得分:0)

“海报”键包含空格。 “海报”。 修复此JSON密钥。

键应与解析相同。您正在尝试解析“海报”,但正在获取“海报”和“海报”。