英文:
I'm getting null pointers when trying to pull Movie Apis
问题
EXCEPTION
2023-04-07T00:26:53.180+03:00 ERROR 21556 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "com.eray.movieAPI.dto.Results.original_language()" because the return value of "com.eray.movieAPI.dto.MovieResponse.result()" is null] with root cause
java.lang.NullPointerException: Cannot invoke "com.eray.movieAPI.dto.Results.original_language()" because the return value of "com.eray.movieAPI.dto.MovieResponse.result()" is null
at com.eray.movieAPI.service.MovieService.saveMovieEntity(MovieService.java:54) ~[classes/:na]
at com.eray.movieAPI.service.MovieService.getMovieFromTheMovieApi(MovieService.java:45) ~[classes/:na]
at com.eray.movieAPI.service.MovieService.getMovieByTitle(MovieService.java:34) ~[classes/:na]
API CLASSES
public record Results(
boolean adult,
String backdrop_path,
Object belongs_to_collection,
Integer budget,
ArrayList<Object> genres,
String homepage,
Integer id,
String imdb_id,
String original_language,
String original_title,
String overview,
Number popularity,
String poster_path,
ArrayList<Object> production_companies,
ArrayList<Object> production_countries,
String release_date,
Integer revenue,
Integer runtime,
ArrayList<Object> spoken_languages,
String status,
String tagline,
String title,
boolean video,
Number vote_average,
Integer vote_count
) {
}
public class Page {
private Integer page;
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Page(Integer page) {
this.page = page;
}
}
RESPONSE CLASS
@JsonIgnoreProperties(ignoreUnknown = true)
public record MovieResponse (
Page page,
Results result) {
}
SERVICE
@Service
public class MovieService {
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate;
private final MovieRepository movieRepository;
private String API_URL = "https://api.themoviedb.org/3/search/movie?api_key=66163767a1794185bacde651631ae753&query=";
public MovieService(RestTemplate restTemplate, MovieRepository movieRepository) {
this.restTemplate = restTemplate;
this.movieRepository = movieRepository;
}
public MovieDto getMovieByTitle(String title){
Optional<MovieEntity> movieEntityOptional = movieRepository.findByTitle(title);
if(!movieEntityOptional.isPresent()){
return MovieDto.convert(getMovieFromTheMovieApi(title));
}
return MovieDto.convert(movieEntityOptional.get());
}
private MovieEntity getMovieFromTheMovieApi(String title){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(API_URL + title, String.class);
try {
MovieResponse movieResponse = objectMapper.readValue(responseEntity.getBody(), MovieResponse.class);
return saveMovieEntity(title , movieResponse);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
private MovieEntity saveMovieEntity(String title, MovieResponse movieResponse){
MovieEntity movieEntity = new MovieEntity(
movieResponse.result().original_language(),
movieResponse.result().original_title(),
movieResponse.result().release_date(),
movieResponse.result().overview(),
movieResponse.result().popularity(),
movieResponse.page().getPage()
);
return movieRepository.save(movieEntity);
}
}
MOVIE ENTITY
@Entity
public class MovieEntity {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID" , strategy = "org.hibernate.id.UUIDGenerator")
private String id;
private String language;
private String title;
private String releaseDate;
private String overview;
private Number popularity;
private Integer page;
}
MOVIE DTO
public record MovieDto(
String language,
String title,
String releaseDate,
String overview,
Number popularity
) {
public static MovieDto convert(MovieEntity from){
return new MovieDto(from.getLanguage(),
from.getTitle(),
from.getReleaseDate(),
from.getOverview(),
from.getPopularity());
}
}
CONTROLLER
@RestController
@RequestMapping("/v1/api/movie")
public class MovieController {
private final MovieService movieService;
public MovieController(MovieService movieService) {
this.movieService = movieService;
}
@GetMapping("/{title}")
public ResponseEntity<MovieDto> getMovieByMovieTitle(@PathVariable @NotBlank String title){
return ResponseEntity.ok(movieService.getMovieByTitle(title));
}
}
API
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/2v3pC01rf0uXnECOM94pjfqk1TY.jpg",
"genre_ids": [
80,
18,
53,
28
],
"id": 75780,
"original_language": "en",
"original_title": "Jack Reacher",
"overview": "When a gunman takes five lives with six shots, all evidence points to the suspect in custody. On interrogation, the suspect offers up a single note: \"Get Jack Reacher!\" So begins an extraordinary chase for the truth, pitting Jack Reacher against an unexpected enemy, with a skill for violence and a secret to keep.",
"popularity": 62.348,
"poster_path": "/uQBbjrLVsUibWxNDGA4Czzo8lwz.jpg",
"release_date": "2012-12-20",
"title": "Jack Reacher",
"video": false,
"vote_average": 6.587,
"vote_count": 6235
},
{
"adult": false,
"backdrop_path": "/ww1eIoywghjoMzRLRIcbJLuKnJH.jpg",
"genre_ids": [
28,
53
],
"id": 343611,
"original_language": "en",
"original_title": "Jack Reacher: Never Go Back",
"overview": "When Major Susan Turner is arrested for treason, ex-investigator Jack Reacher undertakes the challenging task to prove her innocence and ends up exposing a shocking conspiracy.",
"popularity": 54.436,
"poster_path": "/cOg3UT2NYWHZxp41vpxAnVCOC4M.jpg",
"release_date": "2016-10-19",
"title": "Jack Reacher: Never Go Back",
"video": false,
"vote_average": 5.925,
"vote_count": 4322
},
{
"adult": false,
"backdrop_path": null
<details>
<summary>英文:</summary>
EXCEPTION
2023-04-07T00:26:53.180+03:00 ERROR 21556 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.NullPointerException: Cannot invoke "com.eray.movieAPI.dto.Results.original_language()" because the return value of "com.eray.movieAPI.dto.MovieResponse.result()" is null] with root cause
java.lang.NullPointerException: Cannot invoke "com.eray.movieAPI.dto.Results.original_language()" because the return value of "com.eray.movieAPI.dto.MovieResponse.result()" is null
at com.eray.movieAPI.service.MovieService.saveMovieEntity(MovieService.java:54) ~[classes/:na]
at com.eray.movieAPI.service.MovieService.getMovieFromTheMovieApi(MovieService.java:45) ~[classes/:na]
at com.eray.movieAPI.service.MovieService.getMovieByTitle(MovieService.java:34) ~[classes/:na]
API CLASSES
public record Results(
boolean adult,
String backdrop_path,
Object belongs_to_collection,
Integer budget,
ArrayList<Object> genres,
String homepage,
Integer id,
String imdb_id,
String original_language,
String original_title,
String overview,
Number popularity,
String poster_path,
ArrayList<Object> production_companies,
ArrayList<Object> production_countries,
String release_date,
Integer revenue,
Integer runtime,
ArrayList<Object>spoken_languages,
String status,
String tagline,
String title,
boolean video,
Number vote_average,
Integer vote_count
) {
}
public class Page {
private Integer page;
public Integer getPage() {
return page;
}
public void setPage(Integer page) {
this.page = page;
}
public Page(Integer page) {
this.page = page;
}
}
REPONSE CLASS
@JsonIgnoreProperties(ignoreUnknown = true)
public record MovieResponse (
Page page,
Results result) {
}
SERVİCE
@Service
public class MovieService {
private final ObjectMapper objectMapper = new ObjectMapper();
private final RestTemplate restTemplate;
private final MovieRepository movieRepository;
private String API_URL = "https://api.themoviedb.org/3/search/movie?api_key=66163767a1794185bacde651631ae753&query=";
public MovieService(RestTemplate restTemplate, MovieRepository movieRepository) {
this.restTemplate = restTemplate;
this.movieRepository = movieRepository;
}
public MovieDto getMovieByTitle(String title){
Optional<MovieEntity> movieEntityOptional = movieRepository.findByTitle(title);
if(!movieEntityOptional.isPresent()){
return MovieDto.convert(getMovieFromTheMovieApi(title));
}
return MovieDto.convert(movieEntityOptional.get());
}
private MovieEntity getMovieFromTheMovieApi(String title){
ResponseEntity<String> responseEntity = restTemplate.getForEntity(API_URL + title, String.class);
try {
MovieResponse movieResponse = objectMapper.readValue(responseEntity.getBody(), MovieResponse.class);
return saveMovieEntity(title , movieResponse);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
private MovieEntity saveMovieEntity(String title, MovieResponse movieResponse){
MovieEntity movieEntity = new MovieEntity(
movieResponse.result().original_language(),
movieResponse.result().original_title(),
movieResponse.result().release_date(),
movieResponse.result().overview(),
movieResponse.result().popularity(),
movieResponse.page().getPage()
);
return movieRepository.save(movieEntity);
}
MOVIE ENTITY
@Entity
public class MovieEntity {
@Id
@GeneratedValue(generator = "UUID")
@GenericGenerator(name = "UUID" , strategy = "org.hibernate.id.UUIDGenerator")
private String id;
private String language;
private String title;
private String releaseDate;
private String overview;
private Number popularity;
private Integer page;
MOVIE DTO
public record MovieDto(
String language,
String title,
String releaseDate,
String overview,
Number popularity
) {
public static MovieDto convert(MovieEntity from){
return new MovieDto(from.getLanguage(),
from.getTitle(),
from.getReleaseDate(),
from.getOverview(),
from.getPopularity());
}
CONTROLLER
@RestController
@RequestMapping("/v1/api/movie")
public class MovieController {
private final MovieService movieService;
public MovieController(MovieService movieService) {
this.movieService = movieService;
}
@GetMapping("/{title}")
public ResponseEntity<MovieDto> getMovieByMovieTitle(@PathVariable @NotBlank String title){
return ResponseEntity.ok(movieService.getMovieByTitle(title));
}
API
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/2v3pC01rf0uXnECOM94pjfqk1TY.jpg",
"genre_ids": [
80,
18,
53,
28
],
"id": 75780,
"original_language": "en",
"original_title": "Jack Reacher",
"overview": "When a gunman takes five lives with six shots, all evidence points to the suspect in custody. On interrogation, the suspect offers up a single note: "Get Jack Reacher!" So begins an extraordinary chase for the truth, pitting Jack Reacher against an unexpected enemy, with a skill for violence and a secret to keep.",
"popularity": 62.348,
"poster_path": "/uQBbjrLVsUibWxNDGA4Czzo8lwz.jpg",
"release_date": "2012-12-20",
"title": "Jack Reacher",
"video": false,
"vote_average": 6.587,
"vote_count": 6235
},
{
"adult": false,
"backdrop_path": "/ww1eIoywghjoMzRLRIcbJLuKnJH.jpg",
"genre_ids": [
28,
53
],
"id": 343611,
"original_language": "en",
"original_title": "Jack Reacher: Never Go Back",
"overview": "When Major Susan Turner is arrested for treason, ex-investigator Jack Reacher undertakes the challenging task to prove her innocence and ends up exposing a shocking conspiracy.",
"popularity": 54.436,
"poster_path": "/cOg3UT2NYWHZxp41vpxAnVCOC4M.jpg",
"release_date": "2016-10-19",
"title": "Jack Reacher: Never Go Back",
"video": false,
"vote_average": 5.925,
"vote_count": 4322
},
{
"adult": false,
"backdrop_path": null,
"genre_ids": [
99
],
"id": 1045592,
"original_language": "en",
"original_title": "Jack Reacher: When the Man Comes Around",
"overview": "Cast and crew speak on adapting One Shot as the first Jack Reacher film, casting Tom Cruise, earning Lee Child's blessing, additional character qualities and the performances that shape them, Lee Child's cameo in the film, and shooting the film's climax.",
"popularity": 5.992,
"poster_path": null,
"release_date": "2013-05-07",
"title": "Jack Reacher: When the Man Comes Around",
"video": false,
"vote_average": 10.0,
"vote_count": 1
}
],
"total_pages": 1,
"total_results": 3
}
@JsonIgnoreProperties(ignoreUnknown = true)
error when i remove
2023-04-07T00:40:07.691+03:00 ERROR 15896 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "results" (class com.eray.movieAPI.dto.MovieResponse), not marked as ignorable (2 known properties: "result", "page"])
at [Source: (String)"{"page":1,"results":[{"adult":false,"backdrop_path":"/2v3pC01rf0uXnECOM94pjfqk1TY.jpg","genre_ids":[80,18,53,28],"id":75780,"original_language":"en","original_title":"Jack Reacher","overview":"When a gunman takes five lives with six shots, all evidence points to the suspect in custody. On interrogation, the suspect offers up a single note: "Get Jack Reacher!" So begins an extraordinary chase for the truth, pitting Jack Reacher against an unexpected enemy, with a skill for violence and a secret"[truncated 1353 chars]; line: 1, column: 1854] (through reference chain: com.eray.movieAPI.dto.MovieResponse["results"])] with root cause
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "results" (class com.eray.movieAPI.dto.MovieResponse), not marked as ignorable (2 known properties: "result", "page"])
at [Source: (String)"{"page":1,"results":[{"adult":false,"backdrop_path":"/2v3pC01rf0uXnECOM94pjfqk1TY.jpg","genre_ids":[80,18,53,28],"id":75780,"original_language":"en","original_title":"Jack Reacher","overview":"When a gunman takes five lives with six shots, all evidence points to the suspect in custody. On interrogation, the suspect offers up a single note: "Get Jack Reacher!" So begins an extraordinary chase for the truth, pitting Jack Reacher against an unexpected enemy, with a skill for violence and a secret"[truncated 1353 chars]; line: 1, column: 1854] (through reference chain: com.eray.movieAPI.dto.MovieResponse["results"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:61) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.DeserializationContext.handleUnknownProperty(DeserializationContext.java:1132) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:2202) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:540) ~[jackson-databind-2.14.2.jar:2.14.2]com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1705) ~[jackson-databind-2.14.2.jar:2.14.2]
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperties(BeanDeserializerBase.java:1655) ~[jackson-databind-2.14.2.jar:2.14.2]
at
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1405) ~[jackson-databind-2.14.2.jar:2.14.2]
\##################################################################################################################################################################################################################################################################
</details>
# 答案1
**得分**: 0
Your MovieResponse has the field called `result`. According to the Api it needs to be called `results` and should be a list.
also as a tip, you should not post your api-key in the question.
<details>
<summary>英文:</summary>
Your MovieResponse has the field called `result`. According the Api it needs to be called `results` and should be a list.
also as a tip, you should not post your api-key in the question.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论