首页 > 解决方案 > 执行 http 请求并将 Json 格式转换为 dart 对象时出现问题

问题描述

我无法请求 Public Api 并将 Json 格式转换为 Dart 对象。我已经尝试了谷歌上所有可用的解决方案,但它仍然不起作用。当我尝试运行时,“object_patch.dart”文件总是说:

      @patch
      @pragma("vm:entry-point", "call")
      dynamic noSuchMethod(Invocation invocation) {
      // TODO(regis): Remove temp constructor identifier 'withInvocation'.
      throw new NoSuchMethodError.withInvocation(this, invocation);
      }

这就是我将 Json 转换为 Dart 对象的方式:

    class Movie {
    List<Search> search;
    Movie({this.search});

    static Movie fromJson(Map<String, dynamic> json) {
    return Movie(search: List<Search>.from(json['Search']));
      }
    }

    class Search {
    final String imdbID;
    final String title;
    final String year;
    final String poster;

    Search({this.imdbID, this.title, this.year, this.poster});
    static Search fromJson(Map<String, dynamic> json) {
    return Search(
    imdbID: json['imdbID'],
    title: json['Title'],
    year: json['Year'],
     poster: json['Poster'],
      );
     }
    }

这就是我执行http请求的方式:

    Future<List<Movie>> fetchMovie() async {
    final response = await http
    .get('https://fake-movie-database-api.herokuapp.com/api?s=batman');
    final body = jsonDecode(response.body).cast<Map<String, dynamic>>();
    return body.map<Movie>((json) => Movie.fromJson(json)).toList();
    }

这是我的 FutureBuilder :

    class HomePage extends StatefulWidget {
     @override
     _HomePageState createState() => _HomePageState();
      }
 
    class _HomePageState extends State<HomePage> {
     @override
     Widget build(BuildContext context) {
     return FutureBuilder<List<Movie>>(
       future: fetchMovie(),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              return ListView.builder(
                itemCount: 5,
                  itemBuilder: (context, index) {
                    return Container(
                    margin: EdgeInsets.symmetric(horizontal: 25, vertical: 16),
                    height: 200,
                    color: Colors.blue,
                    child: Center(
                    child: Text(snapshot.data[index].search[index].title),
                  ),
                );
              });
             }
        return CircularProgressIndicator();
        });
       }
      }

这是我来自https://fake-movie-database-api.herokuapp.com/的 Rest Api

{"Search":
   [

{   
"imdbID":"tt0096895",
"Title":"Batman",
"Year":"1989",
"Poster":"https://images-na.ssl-images-amazon.com/images/M/MV5BMTYwNjAyODIyMF5BMl5BanBnXkFtZTYwNDMwMDk2._V1_.jpg"
},

{   
"imdbID":"tt0468569",
"Title":"The Dark Knight",
"Year":"2008",
"Poster":"https://ia.media-imdb.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_UX182_CR0,0,182,268_AL_.jpg"
},

{
"imdbID":"tt2975590",
"Title":"Batman v Superman: Dawn of Justice",
"Year":"2016",
"Poster":"https://ia.media-imdb.com/images/M/MV5BYThjYzcyYzItNTVjNy00NDk0LTgwMWQtYjMwNmNlNWJhMzMyXkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_UX182_CR0,0,182,268_AL_.jpg"
},

{   
"imdbID":"tt1345836",
"Title":"The Dark Knight Rises",
"Year":"2012",
"Poster":"https://ia.media-imdb.com/images/M/MV5BMTk4ODQzNDY3Ml5BMl5BanBnXkFtZTcwODA0NTM4Nw@@._V1_UX182_CR0,0,182,268_AL_.jpg"},

{   
"imdbID":"tt0372784",
"Title":"Batman Begins",
"Year":"2005",
"Poster":"https://ia.media-imdb.com/images/M/MV5BYzc4ODgyZmYtMGFkZC00NGQyLWJiMDItMmFmNjJiZjcxYzVmXkEyXkFqcGdeQXVyNDYyMDk5MTU@._V1_UX182_CR0,0,182,268_AL_.jpg"
},

{   
"imdbID":"tt4116284",
"Title":"The LEGO Batman Movie",
"Year":"2017",
"Poster":"https://ia.media-imdb.com/images/M/MV5BMTcyNTEyOTY0M15BMl5BanBnXkFtZTgwOTAyNzU3MDI@._V1_UX182_CR0,0,182,268_AL_.jpg"
},

{   
"imdbID":"tt0112462",
"Title":"Batman Forever",
"Year":"1995",
"Poster":"https://ia.media-imdb.com/images/M/MV5BNWY3M2I0YzItNzA1ZS00MzE3LThlYTEtMTg2YjNiOTYzODQ1XkEyXkFqcGdeQXVyMTQxNzMzNDI@._V1_UX182_CR0,0,182,268_AL_.jpg"},

{
"imdbID":"tt0118688",
"Title":"Batman & Robin",
"Year":"1997",
"Poster":"https://ia.media-imdb.com/images/M/MV5BMGQ5YTM1NmMtYmIxYy00N2VmLWJhZTYtN2EwYTY3MWFhOTczXkEyXkFqcGdeQXVyNTA2NTI0MTY@._V1_UX182_CR0,0,182,268_AL_.jpg"
},

{   
"imdbID":"tt0103776",
"Title":"Batman Returns",
"Year":"1992",
"Poster":"https://ia.media-imdb.com/images/M/MV5BOGZmYzVkMmItM2NiOS00MDI3LWI4ZWQtMTg0YWZkODRkMmViXkEyXkFqcGdeQXVyODY0NzcxNw@@._V1_UX182_CR0,0,182,268_AL_.jpg"
     }
     ]
   }
    

标签: jsonflutterhttpdartrest

解决方案


这对我有用。

模型类

import 'dart:convert';

Movie movieFromJson(String str) => Movie.fromJson(json.decode(str));

String movieToJson(Movie data) => json.encode(data.toJson());

class Movie {
  Movie({
    this.search,
  });

  List<Search> search;

  factory Movie.fromJson(Map<String, dynamic> json) => Movie(
    search: json["Search"] == null ? null : List<Search>.from(json["Search"].map((x) => Search.fromJson(x))),
  );

  Map<String, dynamic> toJson() => {
    "Search": search == null ? null : List<dynamic>.from(search.map((x) => x.toJson())),
  };
}

class Search {
  Search({
    this.imdbId,
    this.title,
    this.year,
    this.poster,
  });

  String imdbId;
  String title;
  String year;
  String poster;

  factory Search.fromJson(Map<String, dynamic> json) => Search(
    imdbId: json["imdbID"] == null ? null : json["imdbID"],
    title: json["Title"] == null ? null : json["Title"],
    year: json["Year"] == null ? null : json["Year"],
    poster: json["Poster"] == null ? null : json["Poster"],
  );

  Map<String, dynamic> toJson() => {
    "imdbID": imdbId == null ? null : imdbId,
    "Title": title == null ? null : title,
    "Year": year == null ? null : year,
    "Poster": poster == null ? null : poster,
  };
}

HTTP 调用

Future<Movie> fetchMovie() async {
    try {
      final response = await http
          .get('https://fake-movie-database-api.herokuapp.com/api?s=batman');
      Map dataMap = jsonDecode(response.body);
      var movies = Movie.fromJson(dataMap);
      return movies;
    } catch (e) {
      print(e);
      return null;
    }
  }

推荐阅读