jackson 如何Map包含long和short成员的JSON字符串

rslzwgfq  于 2022-11-08  发布在  其他
关注(0)|答案(4)|浏览(143)

我需要Map一个JSON字符串,其中包含名为long和short的值:

"status": {
   "long": "Finished",
   "short": "F",
   "elapsed": 90
}

我尝试了以下类:

public class Status {

    @JsonProperty("long")
    public String _long;
    @JsonProperty("short")
    public String _short;
    @JsonProperty("elapsed")
    public Object elapsed;

}

使用以下命令:

objectMapper.readValue(resBody, Response.class);

响应包含状态部分:

{
    "response": {
        "id": 157016,
        "timezone": "UTC",
        "date": "2019-08-10T11:30:00+00:00",
        "timestamp": 1565436600,
        "status": {
            "long": "Long Value",
            "short": "LV",
            "elapsed": 20
        }
    }
}

但我仍然得到以下错误:
无法识别的属性异常:无法识别的字段“long”
如何解决这个问题?我无法控制JSON格式。

btqmn9zl

btqmn9zl1#

当然,这显然不是解决问题的完美方案,但您可能会发现它是一个有用的变通方法:
因为我不关心这些值,所以我只重命名它们的名称,并相应地修改类成员的名称:
我将执行以下操作

@NotNull 
private static String mitigateLongAndShortValueNames(String resBody) { 
   resBody = resBody.replaceAll("\"long\":", "\"longValue\":"); 
   resBody = resBody.replaceAll("\"short\":", "\"shortValue\":"); 
   return resBody; 
}

并且变更了

public class Status {

    @JsonProperty("long")
    public String _long;
    @JsonProperty("short")
    public String _short;
    @JsonProperty("elapsed")
    public Object elapsed;

}

public class Status {

    public String longValue;
    public String shortValue;
    public Object elapsed;

}

对我很有效!

31moq8wy

31moq8wy2#

解决这个问题的方法之一是选择您感兴趣的json部分,结合ObjectMapper#readTree方法,将json转换为JsonNode对象,然后选择JsonNode对象的一部分,使用JsonNode#at方法匹配/response/status路径表达式,如下所示:

//it contains only the status labelled node of your json
JsonNode statusNode = mapper.readTree(json).at("/response/status");

之后,您可以使用ObjectMapper#treeToValue方法将JsonNode转换为Status类,从而获得预期的结果:

JsonNode statusNode = mapper.readTree(json).at("/response/status");
Status status = mapper.treeToValue(statusNode, Status.class);
//ok, it prints {"long":"Long Value","short":"LV","elapsed":20}
System.out.println(mapper.writeValueAsString(status));
ipakzgxi

ipakzgxi3#

完整的例外状况消息应该如下所示:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "long" (class ...), not marked as ignorable (n known properties: ...)
如果你对某些属性不感兴趣,那么在解析过程中使用ignore会更容易、更简洁。可以在数据类上添加注解,也可以在对象Map器上添加DeserializationFeature。
请参阅Jackson with JSON: Unrecognized field, not marked as ignorable

qv7cva1a

qv7cva1a4#

扩展注解:Status"status":...部分没有问题,@JsonProperty()用于处理重命名。您可能将错误的类传递给了readValue()

public class TestClass {
    public static void main(String[] args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        TestClass test= mapper.readValue(
                "{\r\n" + 
                "    \"response\": {\r\n" + 
                "        \"id\": 157016,\r\n" + 
                "        \"status\": {\r\n" + 
                "            \"long\": \"Long Value\",\r\n" + 
                "            \"short\": \"LV\",\r\n" + 
                "            \"elapsed\": 20\r\n" + 
                "        }\r\n" + 
                "    }\r\n" + 
                "}",TestClass.class); // <-- here, it's not Response, but an outer class
        System.out.println(test.response.id);
        System.out.println(test.response.status._long);
    }
    public Response response;         // <-- containing "response"
    static public class Response {
        public long id;
        public Status status;
    }
    static public class Status {
        @JsonProperty("long")
        public String _long;
        @JsonProperty("short")
        public String _short;
        @JsonProperty("elapsed")
        public Object elapsed;
    }
}

显示器

157016
Long Value

正如预期的那样。为了简洁起见,只保留了外部对象的id

相关问题