First: I am aware of the fact, that there are a few topics about deserialization of json arrays, but i still could not figure out, how to store/deserialize a JSON-Array which looks like the following using Jackson into a Map<Integer, Song>, so i can access the Map by the ID integer property from the JSON-file. e.g. songStore.get(2) , where the "2" is the map key and matches the Json entry with id: 2. I have tried different approaches, but i am stuck at the error message:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize >instance of
java.util.LinkedHashMapout of START_ARRAY token at [Source: (BufferedInputStream); line: 1, column: 1]
If I write it to List<Song> instead, it works, but that is not, what i need.
[
{
"id": 1,
"title": "Title 1",
"artist": "Artist 1",
"released": 2012
},
{
"id": 2,
"title": "Title 2",
"artist": "Artist 2",
"album": "Album 2",
"released": 2014
},
{
"id": 3,
"title": "Title 3",
"artist": "Artist 3",
"album": "Album 3",
"released": 2016
},
{...}
]
My POJO looks like this:
public class Song {
@JsonProperty("id")
private Integer id;
@JsonProperty("title")
private String title;
@JsonProperty("artist")
private String artist;
@JsonProperty("album")
private String album;
@JsonProperty("released")
private Integer released;
public Song () { }
public Song (Integer id, String title, String artist, String album, Integer released) {
this.id = id;
this.title = title;
this.artist = artist;
this.album = album;
this.released = released;
}
public Integer getId() {
return id;
}
void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public String getArtist() {
return artist;
}
public String getAlbum() {
return album;
}
public Integer getReleased() {
return released;
}
}
This is my approach, but i cannot get it to work:
// Reads a list of songs from a JSON-file into Map<Integer, Song>
@SuppressWarnings("unchecked")
static Map<Integer, Song> readJSONToSongsMap (String filename) throws FileNotFoundException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
try (InputStream is = new BufferedInputStream(new FileInputStream(filename))) {
return (Map<Integer, Song>) objectMapper.readValue(is, new TypeReference<Map<Integer, Song>>(){});
}
}
EDIT: I found a workaround by creating a List with:
@SuppressWarnings("unchecked")
static List<Song> readJSONToSongs (String filename) throws FileNotFoundException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
try (InputStream is = new BufferedInputStream(new FileInputStream(filename))) {
return (List<Song>) objectMapper.readValue(is, new TypeReference<List<Song>>(){});
}
}
and then just convert the List to a Hashmap by:
private Map<Integer, Song> songStore = new HashMap<Integer, Song>();
List<Song> readSongs = readJSONToSongs("songs.json");
//convert from list to hashmap with key=getId and value=Song.class object
for(Song i : readSongs) songStore.put(i.getId(),i);
But this approach does not satisfy me.
Any help is much appreciated.
Regards.