简体   繁体   English

Java中JSON转换为Object

[英]Conversion of JSON to Object in Java

I am working on a Microservices Project in Java, using Spring Boot and Eureka.我正在 Java 中使用 Spring Boot 和 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-解释- 我从上面使用的 URL 得到以下回复 -

{
    "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 .目标-我想从响应的数据字段中提取Rating对象列表并将其存储为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 ).我将其转换为Map (在getForObject() 方法中传递的 Map.class)。
  2. I get the list of type Map using .get("data").我使用.get("data")获取类型为Map的列表。
  3. This is type casted to List<Rating> .这是类型转换为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?使用上述方法,我可以获得评级为 class 的对象列表。但是,有人可以解释一下这个 map(使用 .get("data") 获得)是如何使用简单类型转换自动转换为 List 的吗? The code doesn't seem to use any Object Mapper like Jackson. Also, I am getting a warning.该代码似乎没有使用任何 Object 映射器,例如 Jackson。此外,我收到警告。 Is there any way to remove it?有什么办法可以去除吗? I can send the List as it is to a GET request.我可以将列表原样发送到 GET 请求。
    But If I try to use a method on the List I get errors-但是如果我尝试使用 List 上的方法,我会出错 -
    Follow Up-跟进-
  4. I tried using stream() and map() on the List I obtained above, but got an error-我尝试在上面获得的列表中使用 stream() 和 map(),但出现错误-
 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() -.map()上出现编译时错误 -

在此处输入图像描述

  1. forEach() gives class cast exception- forEach() 给出 class 强制转换异常-
  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() - 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:您使任务过于复杂,您可以将 RestTemplate 的RestTemplate响应转换为String值,然后使用 jackson 库提取其中的数据部分,如下所示:

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> .这是使用JsonNode#at方法实现的,该方法在您的 json 中定位具有数据label 的特定节点,要将其转换为List<Rating> ,必须使用TypeReference来实例化对通用类型List<Rating>的引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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