【问题标题】:Is it possible to extract a set of database rows with RestTemplate?是否可以使用 RestTemplate 提取一组数据库行?
【发布时间】:2017-04-12 17:23:59
【问题描述】:

我在使用 RestTemplate 从我的数据库中获取多个数据集时遇到了困难。我有许多提取单行的例程,格式如下:

IndicatorModel indicatorModel = restTemplate.getForObject(URL + id, 
IndicatorModel.class);

它们工作正常。但是,如果我尝试提取一组数据,例如:

Map<String, List<S_ServiceCoreTypeModel>> coreTypesMap = 
        restTemplate.getForObject(URL + id, Map.class);

这会在一个

中返回值
Map<String, LinkedHashMap<>> 

格式。有没有一种简单的方法可以返回所需格式的 List 或 Set?

【问题讨论】:

    标签: jpa spring-boot repository resttemplate


    【解决方案1】:

    从根本上说,问题在于您的 Java 对象模型与 json 文档的结构不匹配。您正在尝试将单个 json 元素反序列化为 java 列表。您的 JSON 文档如下所示:

    {
       "serviceCoreTypes":[
          {
             "serviceCoreType":{
                "name":"ALL",
                "description":"All",
                "dateCreated":"2016-06-23 14:46:32.09",
                "dateModified":"2016-06-23 14:46:32.09",
                "deleted":false,
                "id":1
             }
          },
          {
             "serviceCoreType":{
                "name":"HSI",
                "description":"High-speed Internet",
                "dateCreated":"2016-06-23 14:47:31.317",
                "dateModified":"2016-06-23 14:47:31.317",
                "deleted":false,
                "id":2
             }
          }
       ]
    }
    

    但是你不能把serviceCoreTypes变成List,你只能把Json Array变成List。例如,如果您从 json 中删除了不必要的包装器元素,并且您的输入文档看起来像:

    [
      {
        "name": "ALL",
        "description": "All",
        "dateCreated": "2016-06-23 14:46:32.09",
        "dateModified": "2016-06-23 14:46:32.09",
        "deleted": false,
        "id": 1
      },
      {
        "name": "HSI",
        "description": "High-speed Internet",
        "dateCreated": "2016-06-23 14:47:31.317",
        "dateModified": "2016-06-23 14:47:31.317",
        "deleted": false,
        "id": 2
      }
    ]
    

    然后您应该能够将其反序列化为List&lt; S_ServiceCoreTypeModel&gt;。或者,如果您无法更改 json 结构,您可以创建一个 Java 对象模型,通过创建一些包装类来对 json 文档进行建模。比如:

    class ServiceCoreTypes {
      List<ServiceCoreType> serviceCoreTypes;
      ...
    }
    class ServiceCoreTypeWrapper {
      ServiceCoreType serviceCoreType;
      ...
    }
    class ServiceCoreType {
      String name;
      String description;
      ...
    }
    

    【讨论】:

    • 我创建了一个仅包含 List 的包装器。代码现在运行良好。
    【解决方案2】:

    我假设您实际上并不是指数据库,而是您使用 RestTemplate 时提供的宁静服务

    你面临的问题是你想取回一个集合,但是getForObject 方法只能接受一个类型参数,并且无法确定返回的集合的类型是什么。

    我建议您考虑使用RestTemplate.exchange(...) 这应该允许您请求并接收回一个集合类型。

    【讨论】:

    • 我在网上看到了使用 exchange() 的示例,看起来像 ResponseEntity result = restTemplate.exchange(uri, HttpMethod.GET, entity, String.class)。但是,如果我声明一个 ResponseEntity> 结果,我仍然不能将第四个参数作为 List.class 传递,只能作为 List.class - 这给我留下了同样的问题,除非我错过了东西。
    • 请阅读链接方法中的 javadoc 注释。它给出了确切的例子ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt; myBean = new ParameterizedTypeReference&lt;List&lt;MyBean&gt;&gt;() {};ResponseEntity&lt;List&lt;MyBean&gt;&gt; response = template.exchange("http://example.com",HttpMethod.GET, null, myBean);
    • 我喜欢那个解决方案;比我的解决方法干净得多。我编码:
    • RestTemplate restTemplate = new RestTemplate(); ParameterizedTypeReference> myBean = new ParameterizedTypeReference>() {}; ResponseEntity> response = restTemplate.exchange(TestBase.URL + coreTypeURL,HttpMethod.GET, null, myBean);并得到一个嵌套的 JsonMappingException:无法读取文档:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例。
    • 看起来它尝试使用的 json 实际上并不是 S_ServiceCoreTypeModel 的列表,您是否验证了 json 的格式是否符合您的预期?
    【解决方案3】:

    至少现在我有一个可行的解决方案。我更喜欢 Ben 提出的解决方案,我可以将 HTTP 响应正文作为我选择的格式的项目列表获取,但至少在这里我可以从 JSON 节点中提取每个单独的项目。代码:

        S_ServiceCoreTypeModel endModel;
        RestTemplate restTemplate = new RestTemplate();
        JsonNode node = restTemplate.getForObject(URL, JsonNode.class);
        JsonNode allNodes = node.get("serviceCoreTypes");
        JsonNode oneNode = allNodes.get(1);
        ObjectMapper objectMapper = new ObjectMapper();
        endModel = objectMapper.readValue(oneNode.toString(), S_ServiceCoreTypeModel.class);
    

    如果有人对如何使 Ben 的解决方案发挥作用有任何想法,我很想听听。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2023-02-02
      • 1970-01-01
      • 2022-01-17
      相关资源
      最近更新 更多