JSON API 解析问题
JSON API Parsing Issue
我创建了一个 GUI,其中列出了 Hydra 电影数据库 API 中评分最高和最低的电影。当我使用 Compare.Comparing 和 parseInt 解析它以查找最大和最小 IMDB 评级时,我得到一个数字格式异常。我将 max 更改为 parseDouble 只是为了看看是否有帮助,但我得到了一个空指针异常。
我正在放置特别相关的代码和错误,但如果您想要更好的全貌,这里是 link 上 GitHub 项目的 link:
https://github.com/scohen40/cohen-mcw152-MovieDatabaseJSON/tree/bugFixing/src/movieDatabaseApp/movie
这是我的控制器的代码:
package movieDatabaseApp.movie;
import java.awt.event.ActionEvent;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import javax.swing.text.JTextComponent;
import com.google.inject.Inject;
public class MovieController {
private MovieView view;
private MovieService service;
@Inject
public
MovieController(MovieView view, MovieService service) {
this.view = view;
this.service = service;
}
public void refreshData() {
requestHighest2018();
requestLowest2018();
}
public void requestHighest2018() {
requestHighestMovies(service.getAllMovies(),
// requestHighestMovies(service.getMovies2018(),
view.gethTitleField(),
view.gethYearField(),
view.gethRatingField(),
view.gethLanguageField());
}
void requestLowest2018() {
requestLowestMovies(service.getAllMovies(),
// requestLowestMovies(service.getMovies2018(),
view.getlTitleField(),
view.getlYearField(),
view.getlRatingField(),
view.getlLanguageField());
}
private void requestHighestMovies(Call<List<Movie>> call,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
call.enqueue(new Callback<List<Movie>>() {
@Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
List<Movie> list = response.body();
showHighest(list, title, year, rating, language);
}
@Override
public void onFailure(Call<List<Movie>> arg0, Throwable t) {
t.printStackTrace();
}
});
}
private void requestLowestMovies(Call<List<Movie>> call,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
call.enqueue(new Callback<List<Movie>>() {
@Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
List<Movie> list = response.body();
showLowest(list, title, year, rating, language);
}
@Override
public void onFailure(Call<List<Movie>> arg0, Throwable t) {
t.printStackTrace();
}
});
}
public void showHighest(List<Movie> list,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
Optional<Movie> highest = list.stream()
.max(Comparator.comparingDouble(e -> Double.parseDouble(e.getImdb_rating())));
title.setText(String.valueOf(highest.get().getTitle()));
year.setText(String.valueOf(highest.get().getMovie_year()));
rating.setText(String.valueOf(highest.get().getImdb_rating()));
language.setText(String.valueOf(highest.get().getLanguage()));
}
void showLowest(List<Movie> list,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
Optional<Movie> lowest = list.stream()
.min(Comparator.comparing(e -> Integer.parseInt(e.getImdb_rating())));
title.setText(String.valueOf(lowest.get().getTitle()));
year.setText(String.valueOf(lowest.get().getMovie_year()));
rating.setText(String.valueOf(lowest.get().getImdb_rating()));
language.setText(String.valueOf(lowest.get().getMovie_year()));
}
}
这是我在最大解析为双精度和最小解析为整数时得到的错误:
java.lang.NullPointerException
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at movieDatabaseApp.movie.MovieController.lambda[=13=](MovieController.java:109)
at java.util.Comparator.lambda$comparingDoubledcf42ea(Comparator.java:532)
at java.util.function.BinaryOperator.lambda$maxBy(BinaryOperator.java:74)
at java.util.stream.ReduceOpsReducingSink.accept(ReduceOps.java:123)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
at java.util.stream.ReferencePipeline.max(ReferencePipeline.java:515)
at movieDatabaseApp.movie.MovieController.showHighest(MovieController.java:109)
at movieDatabaseApp.movie.MovieController.onResponse(MovieController.java:65)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:123)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException:对于输入字符串:“7.4”
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at movieDatabaseApp.movie.MovieController.lambda(MovieController.java:124)
at java.util.Comparator.lambda$comparinga9974f(Comparator.java:469)
at java.util.function.BinaryOperator.lambda$minBy[=14=](BinaryOperator.java:59)
at java.util.stream.ReduceOpsReducingSink.accept(ReduceOps.java:123)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
at java.util.stream.ReferencePipeline.min(ReferencePipeline.java:520)
at movieDatabaseApp.movie.MovieController.showLowest(MovieController.java:124)
at movieDatabaseApp.movie.MovieController.onResponse(MovieController.java:89)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:123)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
我对 JSON API 集成还很陌生,所以我真的不知道关于这个主题的错误是什么意思,也不知道什么是正常的需要注意的。任何帮助将不胜感激。
此外 - 这是正在解析的原始 JSON,如果您想查看它:https://hydramovies.com/api-v2/?source=http://hydramovies.com/api-v2/current-Movie-Data.csv
我不认为这个错误与 JSON 本身有任何关系。你得到 NPE 或 NFE 是因为你列表中的一部或多部电影没有 IMDB 评级,或者评级中有小数,不能用整数解析,
更新:我最终将 imdb_ratings 的数据类型从 String 切换为 Double,并删除了过滤器和解析器。
现在可以使用了!
你可以在我上面列出的 GitHub 上浏览它。
我创建了一个 GUI,其中列出了 Hydra 电影数据库 API 中评分最高和最低的电影。当我使用 Compare.Comparing 和 parseInt 解析它以查找最大和最小 IMDB 评级时,我得到一个数字格式异常。我将 max 更改为 parseDouble 只是为了看看是否有帮助,但我得到了一个空指针异常。
我正在放置特别相关的代码和错误,但如果您想要更好的全貌,这里是 link 上 GitHub 项目的 link: https://github.com/scohen40/cohen-mcw152-MovieDatabaseJSON/tree/bugFixing/src/movieDatabaseApp/movie
这是我的控制器的代码:
package movieDatabaseApp.movie;
import java.awt.event.ActionEvent;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import javax.swing.text.JTextComponent;
import com.google.inject.Inject;
public class MovieController {
private MovieView view;
private MovieService service;
@Inject
public
MovieController(MovieView view, MovieService service) {
this.view = view;
this.service = service;
}
public void refreshData() {
requestHighest2018();
requestLowest2018();
}
public void requestHighest2018() {
requestHighestMovies(service.getAllMovies(),
// requestHighestMovies(service.getMovies2018(),
view.gethTitleField(),
view.gethYearField(),
view.gethRatingField(),
view.gethLanguageField());
}
void requestLowest2018() {
requestLowestMovies(service.getAllMovies(),
// requestLowestMovies(service.getMovies2018(),
view.getlTitleField(),
view.getlYearField(),
view.getlRatingField(),
view.getlLanguageField());
}
private void requestHighestMovies(Call<List<Movie>> call,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
call.enqueue(new Callback<List<Movie>>() {
@Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
List<Movie> list = response.body();
showHighest(list, title, year, rating, language);
}
@Override
public void onFailure(Call<List<Movie>> arg0, Throwable t) {
t.printStackTrace();
}
});
}
private void requestLowestMovies(Call<List<Movie>> call,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
call.enqueue(new Callback<List<Movie>>() {
@Override
public void onResponse(Call<List<Movie>> call, Response<List<Movie>> response) {
List<Movie> list = response.body();
showLowest(list, title, year, rating, language);
}
@Override
public void onFailure(Call<List<Movie>> arg0, Throwable t) {
t.printStackTrace();
}
});
}
public void showHighest(List<Movie> list,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
Optional<Movie> highest = list.stream()
.max(Comparator.comparingDouble(e -> Double.parseDouble(e.getImdb_rating())));
title.setText(String.valueOf(highest.get().getTitle()));
year.setText(String.valueOf(highest.get().getMovie_year()));
rating.setText(String.valueOf(highest.get().getImdb_rating()));
language.setText(String.valueOf(highest.get().getLanguage()));
}
void showLowest(List<Movie> list,
JTextComponent title,
JTextComponent year,
JTextComponent rating,
JTextComponent language)
{
Optional<Movie> lowest = list.stream()
.min(Comparator.comparing(e -> Integer.parseInt(e.getImdb_rating())));
title.setText(String.valueOf(lowest.get().getTitle()));
year.setText(String.valueOf(lowest.get().getMovie_year()));
rating.setText(String.valueOf(lowest.get().getImdb_rating()));
language.setText(String.valueOf(lowest.get().getMovie_year()));
}
}
这是我在最大解析为双精度和最小解析为整数时得到的错误:
java.lang.NullPointerException
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at movieDatabaseApp.movie.MovieController.lambda[=13=](MovieController.java:109)
at java.util.Comparator.lambda$comparingDoubledcf42ea(Comparator.java:532)
at java.util.function.BinaryOperator.lambda$maxBy(BinaryOperator.java:74)
at java.util.stream.ReduceOpsReducingSink.accept(ReduceOps.java:123)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
at java.util.stream.ReferencePipeline.max(ReferencePipeline.java:515)
at movieDatabaseApp.movie.MovieController.showHighest(MovieController.java:109)
at movieDatabaseApp.movie.MovieController.onResponse(MovieController.java:65)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:123)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
java.lang.NumberFormatException:对于输入字符串:“7.4”
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at movieDatabaseApp.movie.MovieController.lambda(MovieController.java:124)
at java.util.Comparator.lambda$comparinga9974f(Comparator.java:469)
at java.util.function.BinaryOperator.lambda$minBy[=14=](BinaryOperator.java:59)
at java.util.stream.ReduceOpsReducingSink.accept(ReduceOps.java:123)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:479)
at java.util.stream.ReferencePipeline.min(ReferencePipeline.java:520)
at movieDatabaseApp.movie.MovieController.showLowest(MovieController.java:124)
at movieDatabaseApp.movie.MovieController.onResponse(MovieController.java:89)
at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:123)
at okhttp3.RealCall$AsyncCall.execute(RealCall.java:153)
at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
我对 JSON API 集成还很陌生,所以我真的不知道关于这个主题的错误是什么意思,也不知道什么是正常的需要注意的。任何帮助将不胜感激。
此外 - 这是正在解析的原始 JSON,如果您想查看它:https://hydramovies.com/api-v2/?source=http://hydramovies.com/api-v2/current-Movie-Data.csv
我不认为这个错误与 JSON 本身有任何关系。你得到 NPE 或 NFE 是因为你列表中的一部或多部电影没有 IMDB 评级,或者评级中有小数,不能用整数解析,
更新:我最终将 imdb_ratings 的数据类型从 String 切换为 Double,并删除了过滤器和解析器。 现在可以使用了!
你可以在我上面列出的 GitHub 上浏览它。