简体   繁体   中英

Conversion of JSON to Object in Java

I am working on a Microservices Project in Java, using Spring Boot and Eureka. I came across a scenario where I fetch the data from another microservice using-

        List<Rating> ratings=(List<Rating>) restTemplate.getForObject("http://localhost:8083/microservices/rating/get-all-ratings-by-user?userId=ddb8e2a9-ac6f-460d-a43e-eae23d18450c", Map.class).get("data");

I get a warning on this line-
在此处输入图像描述

Explanation- I get the following response from the URL I used above-

{
    "data": [
        {
            "ratingId": "6140b240-9a97-430d-92b9-0fcfa8edc96f",
            "userId": "ddb8e2a9-ac6f-460d-a43e-eae23d18450c",
            "hotelId": "1093aa3f-8529-4330-8ce8-caa82546200b",
            "rating": 4,
            "feedback": "Died peacefully"
        }
    ],
    "message": "Success",
    "code": "2000"
}

Aim- I want to extract the list of Rating objects from the response's data field and store it as a List . Further, I want to iterate over it and perform other operations.

  1. I convert it to a Map (Map.class passed in getForObject() method ).
  2. I get the list of type Map using .get("data").
  3. This is type casted to List<Rating> .
    My Question-
    Using this above approach I am able to obtain a list of objects of Rating class. But, can somebody explain how this map (obtained using.get("data")) automatically gets converted to List using simple type conversion? The code doesn't seem to use any Object Mapper like Jackson. Also, I am getting a warning. Is there any way to remove it? I can send the List as it is to a GET request.
    But If I try to use a method on the List I get errors-
    Follow Up-
  4. I tried using stream() and map() on the List I obtained above, but got an error-
 ratings=ratings.stream().map(rating->{
            //api call to hotel service to obtain the hotel
            Hotel hotel=(Hotel) restTemplate.getForEntity("http://localhost:8086/microservices/hotel/get-hotel-by-id?hotelId="+rating.getHotelId(), Map.class).getBody().get("data");
            logger.info("fetched hotel: ", hotel);
            rating.setHotel(hotel);
        }).collect(Collectors.toList());

Got a compile-time error on the .map() -

在此处输入图像描述

  1. forEach() gives class cast exception-
  ratings.forEach((rating)->{
            //api call to hotel service to obtain the hotel
            Hotel hotel=(Hotel) restTemplate.getForEntity("http://localhost:8086/microservices/hotel/get-hotel-by-id?hotelId="+rating.getHotelId(), Map.class).getBody().get("data");
            logger.info("fetched hotel: ", hotel);
            rating.setHotel(hotel);
      });

Error on forEach() -

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.example.user_service.entities.Rating (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; com.example.user_service.entities.Rating is in unnamed module of loader org.springframework.boot.devtools.restart.classloader.RestartClassLoader @db2af5f)
        at java.base/java.util.ArrayList.forEach(Unknown Source) ~[na:na]
        at com.example.user_service.ServiceImpl.UserServiceImpl.getUser(UserServiceImpl.java:84) ~[classes/:na]
        at com.example.user_service.controller.UserController.getUserById(UserController.java:53) ~[classes/:na]

You are overcomplicating the task, you can convert the json response from your RestTemplate to a String value, then extract the data part inside of it with jackson library like below:

JsonNode root =mapper.readTree(json); //<--convert the json string to a JsonNode
JsonNode data = root.at("/data"); //<-- selecting the "data" part
//conversion to List<Rating> avoid problems due to list type erasure
//with the help of jackson TypeReference class
List<Rating> ratings = mapper.convertValue(data, new TypeReference<List<Rating>>() {});

This is achieved using the JsonNode#at method that locates the specific node with data label inside your json, to convert it to a List<Rating> it is necessary to use TypeReference to instantiate reference to generic type List<Rating> .

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