![](/img/trans.png)
[英]Getting 500 internal server error when trying to use the put and post methods on postman to my spring rest app
[英]Spring Boot - Cannot use get from Postman after adding a song: NoSuchElementException (Spring) and Internal Server Error (postman)
我們的老師要求我們創建一個 spring 引導應用程序來管理具有一對多關系的歌曲和專輯使用 DTO,但是我們需要在 controller 中手動進行映射,我們不能使用外部庫。 關鍵是,無論我如何嘗試更改方法,它總是會導致 Spring 錯誤(我們使用 PostgreSQL 並且在 pgadmin 中我可以毫無問題地看到數據)。
例如,使用我現在共享的代碼,我最初可以使用獲取歌曲和專輯,但如果我添加一首新歌曲,則獲取方法會導致 NoSuchElementException,
特別是這一行: at com.newplaylist.controller.SongController.getSongs(SongController.java:55)
指向這一行: songs.add(new SongDTO((Song) iterator.next(), iterator.next().getAlbum()));
並且我還在 Postman 上收到 500 內部服務器錯誤。在此先感謝您的幫助,如果需要,我可以添加完整的異常跟蹤。
import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;
public class SongDTO {
private Integer id;
private String author, title;
private AlbumDTO album;
public SongDTO() {
}
public SongDTO(Song song) {
this.id = song.getId();
this.author = song.getAuthor();
this.title = song.getTitle();
}
public SongDTO(Song song, Album album) {
this.id = song.getId();
this.author = song.getAuthor();
this.title = song.getTitle();
this.album = new AlbumDTO(album, true);
}
// getters and setters...
}
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;
public class AlbumDTO {
private Integer id;
private String name;
private String production;
private Set<SongDTO> songs;
public AlbumDTO() {
}
public AlbumDTO(Album album) {
this.id = album.getId();
this.name = album.getName();
this.production = album.getProduction();
}
public AlbumDTO(Album album, boolean lazy) {
this.id = album.getId();
this.name = album.getName();
this.production = album.getProduction();
songs = new HashSet<SongDTO>();
album.getSongs();
if (!lazy) {
for (Iterator<Song> iterator = album.getSongs().iterator(); iterator.hasNext();) {
songs.add(new SongDTO((Song) iterator.next()));
}
}
}
// getters and setters...
}
package com.newplaylist.controller;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.newplaylist.dto.AlbumDTO;
import com.newplaylist.dto.SongDTO;
import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;
import com.newplaylist.service.SongService;
@RestController
@RequestMapping("/song")
public class SongController {
@Autowired
SongService songService;
public void init() {
}
@PostMapping("/add")
public ResponseEntity<?> addSong(@RequestBody Song song) {
try {
return new ResponseEntity<SongDTO>(new SongDTO(songService.addSong(song), song.getAlbum()), HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<Object>(e.getStackTrace(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/all")
public ResponseEntity<Collection<SongDTO>> getSongs() {
Collection<SongDTO> songs = new ArrayList<>();
try {
for (Iterator<Song> iterator = songService.getSongs().iterator(); iterator.hasNext();) {
songs.add(new SongDTO((Song) iterator.next(), iterator.next().getAlbum()));
}
return new ResponseEntity<Collection<SongDTO>>(songs, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
package com.newplaylist.controller;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.newplaylist.dto.AlbumDTO;
import com.newplaylist.dto.SongDTO;
import com.newplaylist.entity.Album;
import com.newplaylist.entity.Song;
import com.newplaylist.service.AlbumService;
@RestController
@RequestMapping("/album")
public class AlbumController {
@Autowired
AlbumService albumService;
@PostMapping("/add")
public ResponseEntity<?> addAlbum(@RequestBody Album album) {
try {
return new ResponseEntity<AlbumDTO>(new AlbumDTO(albumService.addAlbum(album), true), HttpStatus.CREATED);
} catch (Exception e) {
e.printStackTrace();
return new ResponseEntity<Object>(e.getStackTrace(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@GetMapping("/all")
public ResponseEntity<Collection<AlbumDTO>> getAlbums() {
Collection<AlbumDTO> albums = new ArrayList<>();
try {
for (Iterator<Album> iterator = albumService.getAlbums().iterator(); iterator.hasNext();) {
albums.add(new AlbumDTO((Album) iterator.next(), false));
}
return new ResponseEntity<Collection<AlbumDTO>>(albums, HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<>(null, HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
package com.newplaylist.entity;
import java.util.Set;
import com.fasterxml.jackson.annotation.JsonBackReference;
import com.fasterxml.jackson.annotation.JsonManagedReference;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
@Entity
public class Album {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String production;
//@JsonBackReference // per scegliere quale reference stampare, altrimenti andrebbe in loop infinito
@OneToMany(mappedBy = "album", cascade = CascadeType.ALL)
private Set<Song> songs;
public Album() {
super();
}
public Album(Integer id, String name, String production, Set<Song> songs) {
super();
this.id = id;
this.name = name;
this.production = production;
this.songs = songs;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProduction() {
return production;
}
public void setProduction(String production) {
this.production = production;
}
public Set<Song> getSongs() {
return songs;
}
public void setSongs(Set<Song> songs) {
this.songs = songs;
}
}
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
@Entity
public class Song {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String author, title;
// @OneToOne
// @JoinColumn(name = "album") // campo album della tab song. questo campo contiene un id che si collega all'entità Album, perciò fai l'inner join con essa.
// private Album album;
// @ManyToOne
// @JoinColumn(name = "playlist")
// private Playlist playlist;
@ManyToOne
@JoinColumn(name = "album", nullable = false)
//@JsonManagedReference
private Album album;
public Song() {}
public Song(Integer id, String author, String title) {
super();
this.id = id;
this.author = author;
this.title = title;
}
public Song(Integer id, String author, String title, Album album) {
super();
this.id = id;
this.author = author;
this.title = title;
this.album = album;
}
// getters and setters
}
我認為問題出在其中一個類中,但如果您需要其他內容,我可以將項目上傳到 GitHub。
你需要這樣的東西
try {
for (Iterator<Song> iterator = songService.getSongs().iterator(); iterator.hasNext();) {
Song currentSong = iterator.next();
songs.add(new SongDTO(currentSong, currentSong.getAlbum()));
}
調用 iterator.next() 將始終獲取一首新歌曲,這意味着 iterator.next().getAlbum() 將獲取與集合中的下一首歌曲相對應的專輯,而不是您已經獲取的當前歌曲第一次調用 iterator.next()。 此外,如果您的歌曲數量為奇數,則會導致異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.