简体   繁体   中英

restAPI json array in Object extract

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);
            }
        };

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM