Reputation: 7
I am getting an error: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<com.hatach.backend.models.
Probably because my data type during ObjectMapper in Main or ArrayList<> in Entity is wrong... I don't know how to go about fixing it because I don't seem to understand where the error is specifically, or if I should go about it a different way (ie: not do business logic in main and create a serviceImpl and and maybe a dto package.
I guess this question is 2 folds: (1) how to fix this error. (2) what's the good standardized best way to go about stamping json data in restAPIs, which we can then sort by messing with the url. ie localhost:8080/recipes?name=scrambledEggs
1) JSON File
"recipes": [
{
"name": "scrambledEggs",
"ingredients": [
"1 tsp oil",
"2 eggs",
"salt"
],
"instructions": [
"Beat eggs with salt",
"Heat oil in pan",
"Add eggs to pan when hot",
"Gather eggs into curds, remove when cooked",
"Salt to taste and enjoy"
]
},
{
"name": "garlicPasta",
"ingredients": [
"500mL water",
"100g spaghetti",
"25mL olive oil",
"4 cloves garlic",
"Salt"
],
"instructions": [
"Heat garlic in olive oil",
"Boil water in pot",
"Add pasta to boiling water",
"Remove pasta from water and mix with garlic olive oil",
"Salt to taste and enjoy"
]
2) Entity
public class RecipesInfo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private ArrayList<RecipesFile> recipes;
//get + set
public class RecipesFile {
private String name;
private ArrayList<String> ingredients;
private ArrayList<String> instructions;
//get + set
3) Main file
ublic class ApiApplication {
public static void main(String[] args) {
SpringApplication.run(ApiApplication.class, args);
}
@Bean
CommandLineRunner runner(RecipesService recipesService) {
return args -> {
ObjectMapper mapper = new ObjectMapper();
TypeReference<ArrayList<RecipesInfo>> typeReference = new TypeReference<ArrayList<RecipesInfo>>() {};
InputStream inputStream =TypeReference.class.getResourceAsStream("/json/data.json");
try {
ArrayList<RecipesInfo> recipes = mapper.readValue(inputStream, typeReference);
recipesService.save(recipes);
System.out.println("data saved: recipes");
} catch (IOException e) {
System.out.println("unable to save data: recipes");
System.out.println(e);
}
};
Upvotes: 0
Views: 272
Reputation: 41
A JSON should contain an array or a JSON object. In your case, based on your entity, you should add curly brackets around your recipes
array
{
"recipes": [
{
"name": "scrambledEggs",
"ingredients": [
"1 tsp oil",
"2 eggs",
"salt"
],
"instructions": [
"Beat eggs with salt",
"Heat oil in pan",
"Add eggs to pan when hot",
"Gather eggs into curds, remove when cooked",
"Salt to taste and enjoy"
]
},
{
"name": "garlicPasta",
"ingredients": [
"500mL water",
"100g spaghetti",
"25mL olive oil",
"4 cloves garlic",
"Salt"
],
"instructions": [
"Heat garlic in olive oil",
"Boil water in pot",
"Add pasta to boiling water",
"Remove pasta from water and mix with garlic olive oil",
"Salt to taste and enjoy"
]
]
}
After that you can simply deserialize a single RecipesInfo
instead of its collection
RecipesInfo recipes = mapper.readValue(inputStream, RecipesInfo.class);
Also, I noticed your inner RecipesFile
class is not static
. Object Mapper won't be able to create an instance of RecipesFile
class without that
public class RecipesInfo {
...
public static class RecipesFile {
private String name;
private ArrayList<String> ingredients;
private ArrayList<String> instructions;
//get + set
...
Regarding the second question, you can check the following Stackoverflow article.
Upvotes: 1