java - 如何映射包含名为 long 和 short 的成员的 JSON 字符串

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

"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
        }
    }
}

但我仍然收到以下错误:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:无法识别的字段“long”

如何解决这个问题?我无法控制 JSON 格式。

回答1

好吧,这显然不是解决问题的完美方法,但人们可能会发现它是一种有用的解决方法:

由于我不关心这些 values,我将重命名它们的名称并相应地调整类成员名称:

在 json 字符串 resBody 我得到的响应中,我将执行以下操作

@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;

}

它对我有用!

回答2

解决问题的方法之一是选择您感兴趣的 json 部分,结合将您的 json 转换为 JsonNode 对象的 https://fasterxml.github.io/jackson-databind/javadoc/2.12/com/fasterxml/jackson/databind/ObjectMapper.html#readTree-java.lang.String- 方法,然后选择 JsonNode 的部分您正在使用与 /response/status 路径表达式匹配的 https://fasterxml.github.io/jackson-databind/javadoc/2.12/com/fasterxml/jackson/databind/JsonNode.html#at-java.lang.String- 方法查找的对象,如下所示:

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

在您可以使用 https://fasterxml.github.io/jackson-databind/javadoc/2.12/com/fasterxml/jackson/databind/ObjectMapper.html#treeToValue-com.fasterxml.jackson.core.TreeNode-java.lang.Class- 方法将 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));

回答3

完整的异常消息应如下所示:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "long" (class ...), not marked as ignorable (n known properties: ...)

如果您对某些属性不感兴趣,那么在解析过程中使用 ignore 会更容易、更清晰。在数据类上使用注释或在 objectmapper 上使用 DeserializationFeature。

请参阅 https://stackoverflow.com/questions/4486787/jackson-with-json-unrecognized-field-not-marked-as-ignorable

回答4

扩展评论: 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

相似文章

html - 如何将可滚动内容与标题居中?

我正在尝试集中一些内容。内容大于父级,因此需要滚动。顶部还有一个标题。出于某种原因,滚动高度会剪切可滚动内容。关于我应该如何解决这个问题的想法?这是小提琴:https://jsfiddle.net/x...

随机推荐

最新文章