java POJO to JSON - writing to string - getting {“traversableAgain”:true,“empty”:与Jackson

zf2sa74q  于 2023-04-28  发布在  Java
关注(0)|答案(2)|浏览(184)

我在我的Postgres DB中输入json,并将其作为POJO获取。然后我尝试将我的POJO写入StringPOJO被正确填充,但是当Jackson将其写入String时,我得到了{"traversableAgain" : true, "empty" : false},因为嵌套的JSONPOJO中的类型是Object
我的POJO

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
public class MyClass {

  private String property1;
  private Double property2;
  private Boolean property3;
  private Object problematicProperty;

}

我从DB中检索的JSON:

{
"property1" : "randomString",
"property2" : 0.3,
"property3" : false,
"problematicProperty" :  {
                "yearFromDate": [
                    "dob",
                    "yyyyMMdd"
                ]
            }
}

我的代码:

MyClass myPOJO = myRepository.getOne(pojoID);
ObjectMapper obj = getObjectMapper();
obj.enable(SerializationFeature.INDENT_OUTPUT);
obj.enable(SerializationFeature.WRAP_ROOT_VALUE);

String stringLayout = obj
        .writerWithDefaultPrettyPrinter()
        .writeValueAsString(myPOJO);

当我打印stringLayout时,我得到:

{
"property1" : "randomString",
"property2" : 0.3,
"property3" : false,
"problematicProperty" :  {"traversableAgain" : true, "empty" : false}
}

而不是

{
"property1" : "randomString",
"property2" : 0.3,
"property3" : false,
"problematicProperty" :  {
                "yearFromDate": [
                    "dob",
                    "yyyyMMdd"
                ]
            }
}

我用的是java。lang.Object类型因为problematicProperty是“动态的”,有时会像上面那样嵌套json,有时候会是string e。例如:

"problematicProperty" :  "randomText"

测试时,如果我使用com.fasterxml.jackson.databind.node.ObjectNode类型而不是Object,则字符串被正确写入。但是我不能在Hibernate中使用ObjectNode
为什么会发生这种情况,是否有方法配置objectMapperjava.lang.Object(实际上是嵌套的JSON)正确写入String

j0pj023g

j0pj023g1#

this答案的启发,我添加了此链接

objectMapper.registerModule(new DefaultScalaModule());

现在它工作正常,代码看起来像这样:

MyClass myPOJO = myRepository.getOne(pojoID);
ObjectMapper obj = getObjectMapper();
objectMapper.registerModule(new DefaultScalaModule());
obj.enable(SerializationFeature.INDENT_OUTPUT);
obj.enable(SerializationFeature.WRAP_ROOT_VALUE);

String stringLayout = obj
    .writerWithDefaultPrettyPrinter()
    .writeValueAsString(myPOJO);
kqhtkvqz

kqhtkvqz2#

举一个完整的例子会有所帮助。如果我从你的代码中创建一个虚拟的例子-见下文,那么它就能按预期工作。
{"traversableAgain" : true, "empty" : false} JSON很可能来自Scala类型,可能是Scala Map。如果不知道这些数据来自哪里,很难说如何修复它。一个可能的解决方案是将problematicProperty字段类型更改为(Java)Map,并在构造对象时转换Scala Map。

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.*;

public class JacksonTest {

    @JsonIgnoreProperties(ignoreUnknown = true)
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class MyClass {

        private String property1;
        private Double property2;
        private Boolean property3;
        private Object problematicProperty;

        public MyClass() {}

        public MyClass(String property1, Double property2, Boolean property3, Object problematicProperty) {
            this.property1 = property1;
            this.property2 = property2;
            this.property3 = property3;
            this.problematicProperty = problematicProperty;
        }

        // getters and setters
    }

    private static final String TEST_JSON = "{\n" +
            "\"property1\" : \"randomString\",\n" +
            "\"property2\" : 0.3,\n" +
            "\"property3\" : false,\n" +
            "\"problematicProperty\" :  {\n" +
            "                \"yearFromDate\": [\n" +
            "                    \"dob\",\n" +
            "                    \"yyyyMMdd\"\n" +
            "                ]\n" +
            "            }\n" +
            "}";

    public static void main(String[] args) throws JsonProcessingException {
        final ObjectMapper obj = new ObjectMapper();
        obj.enable(SerializationFeature.INDENT_OUTPUT);
        obj.enable(SerializationFeature.WRAP_ROOT_VALUE);

        MyClass myPOJO = obj.readValue(TEST_JSON, MyClass.class);

        final String json = obj
                .writerWithDefaultPrettyPrinter()
                .writeValueAsString(myPOJO);

        System.out.println(json);
    }
}

相关问题