Java从ResponseEntity获取嵌套值,而不创建pojo

oxiaedzo  于 2023-01-01  发布在  Java
关注(0)|答案(3)|浏览(208)

我尝试从ResponseEntity获取一个嵌套值,但我尝试这样做,而不必为每个可能的项目创建一个pojo,因为这是一个第三方API响应。
Postman中出现的响应示例. getBody():

{
    "message": "2 records found",
    "records": [
        {
            "Account": {
                "Id": "1",
                "Name": "Foo Inc"
            },
            "CaseNumber": "200",
            "Contact": {
                "FirstName": "Foo",
                "LastName": "Bar"
            },
            "Status": "In Progress",
            "StatusMessage": "We are working on this."
        },
        {
            "Account": {
                 "Id": "1",
                 "Name": "Foo Inc"
            },
            "CaseNumber": "100",
            "Contact": {
                "FirstName": "Foo",
                "LastName": "Bar"
            },
            "Status": "Closed"
        }

    ]
}

基本上,如果我在JS,我会寻找:

for(let record of res.body.records){
   if(record && record.CaseNumber === "200"){
      console.log(record.Status)
}
res.body.records[0].Status

目前,他们正在执行此操作以检查响应是否为空:

ResponseEntity<Object> response = restTemplate.exchange(sfdcURL, HttpMethod.POST, entity, Object.class);

LinkedHashMap<Object, Object> resMap = (LinkedHashMap<Object, Object>) response.getBody();
        
List<Object> recordsList = (List<Object>) resMap.get("records");

if (recordsList.size() <= 0) { return error }

但是我需要得到"状态"的值,而且我需要在不创建pojo的情况下这样做。
我非常感谢有关如何在Java中执行此操作的任何指导

    • 更新**

因此,响应. getBody()被返回,当它显示在Postman中时,看起来就像上面显示的漂亮JSON。

System.out.println(response.getBody().toString())

它看起来像:

{message=2 Records Found, records=[{Account={Id=1, Name=Foo Inc}, CaseNumber=200, Contact={FirstName=Foo, LastName=Bar}, //etc

更糟糕的是,其中一个字段在控制台中显示如下(包括换行符):

[...], Status=In Progress, LastEmail=From: noreply@blah.com
Sent: 2022-08-08 10:14:54
To: foo@bar.com
Subject: apropos case #200

Hello Foo,
We are working on your case and stuff

Thank you,
us, StatusMessage=We are working on this., OtherFields=blah, [...]

text.replaceAll("=",":")可能会有所帮助,但不会添加引号,也无助于分隔电子邮件块。
我怎样才能使ObjectMapper和JSONObject这样的响应工作呢?

x0fgdtte

x0fgdtte1#

请不要像Hiran的例子那样使用Genson,这个库自2019年以来就没有更新过,有很多脆弱的依赖项!
使用JacksonGson
下面介绍如何将字符串序列化为JacksonJsonNode

ObjectMapper mapper = new ObjectMapper();

String json = ...;
JsonNode node = mapper.readTree(json);

如果要将JSON对象字符串序列化为Map

ObjectMapper mapper = new ObjectMapper();

String json = ...;
Map<String, Object> map = mapper.readValue(json, HashMap.class);

您可以阅读更多关于JsonNodehere的信息和here教程。

bihw5rsg

bihw5rsg2#

您可以使用JSON-Java库,代码如下所示:

JSONObject jsonObject = new JSONObject(JSON_STRING);
String status = jsonObject.getJSONArray("records")
                .getJSONObject(0)
                .getString("Status");
System.out.println(status);

或者在一个循环中

JSONArray jsonArray = new JSONObject(jsonString).getJSONArray("records");
for(int i =0; i < jsonArray.length(); i++) {
    String status = jsonArray
                .getJSONObject(i)
                .getString("Status");
    System.out.println(status);
}
brvekthn

brvekthn3#

因此,响应.getBody()被返回,当它显示在Postman中时,看起来就像上面显示的漂亮JSON。
...
text.replaceAll(“=",“:“)可能会有所帮助,但不会添加引号,也无助于分隔电子邮件块。
我怎样才能使ObjectMapper和JSONObject这样的响应工作呢?
首先,Jackson是SpringWeb用来序列化和反序列化JSON的默认消息转换器,您需要引入任何依赖项。
其次,进程序列化/反序列化由框架自动处理,因此在许多情况下您不需要自己处理ObjectMapper
为了强调,我将再次:在Spring中的大多数情况下,你不需要自己处理行JSON,在RestTemplate.exchange()方法生成的ResponseEntiry<Object>的主体中,你有一个伪装成ObjectLinkedHashMap,它不是一个行JSON(如果你知道为什么它是LinkedHashMap,因为Jackson就是这样存储信息的,而且它是Object的子类,就像Java中的任何其他类一样)。当你在Map的任何实现上调用toString()时,你会得到一个键和一个值之间的=
所以,你在更新的问题中提到的问题是人为的。
如果你想用Map而不是一个具有正确输入属性的对象来拨号,下面是你可以做到的:

RestTemplate restTemplate = new RestTemplate();
        
ResponseEntity<LinkedHashMap<String, Object>> response = restTemplate.exchange(
    sfdcURL, HttpMethod.POST, entity, new ParameterizedTypeReference<>() {}
);
    
Map<String, Object> resMap = response.getBody();
    
List<Object> recordsList = (List<Object>) resMap.get("records");
    
if (recordsList.isEmpty()) { ... }

如果你想要修剪的值中有多余的行,那么作为一种补救措施,你可以引入一个自定义的Jackson模块,声明一个反序列化器来处理前导/尾随空格和新行,如this answer中所述。模块中的反序列化将被默认应用,其他选项将需要创建代表域对象的类,出于某些原因,你希望避免。

相关问题