杰克逊:是否有可能将父对象的属性包含在嵌套对象中?

时间:2013-10-04 21:38:51

标签: json jackson deserialization

我正在使用Jackson序列化/反序列化JSON对象。

我有Study对象的以下JSON:

{
    "studyId": 324,
    "patientId": 12,
    "patient": {
        "name": "John",
        "lastName": "Doe"
    }
}

更新:不幸的是,无法修改JSON结构。这是问题的一部分。

我想将对象反序列化为以下类:

public class Study {
    Integer studyId;
    Patient patient;
}

public class Patient {
    Integer patientId;
    String name;
    String lastName;
}

是否可以在patientId对象中包含Patient属性?

我可以将patient对象反序列化为Patient类(包含相应的namelastName属性),但无法包含patientId } property。

有什么想法吗?

4 个答案:

答案 0 :(得分:6)

您可以为自己的用例使用自定义反序列化程序。这是它的样子:

import java.io.IOException;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;

public class StudyDeserializer extends JsonDeserializer<Study>
{
    @Override
    public Study deserialize(JsonParser parser, DeserializationContext context)
        throws IOException, JsonProcessingException
    {
        JsonNode studyNode = parser.readValueAsTree();

        Study study = new Study();
        study.setStudyId(studyNode.get("studyId").asInt());

        Patient patient = new Patient();
        JsonNode patientNode = studyNode.get("patient");
        patient.setPatientId(studyNode.get("patientId").asInt());
        patient.setName(patientNode.get("name").asText());
        patient.setLastName(patientNode.get("lastName").asText());
        study.setPatient(patient);

        return study;
    }
}

Study类中指定上述类作为反序列化器:

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

@JsonDeserialize(using = StudyDeserializer.class)
public class Study
{
    Integer studyId;
    Patient patient;

    // Getters and setters
}

现在,您指定的JSON输入应按预期反序列化。

答案 1 :(得分:1)

没有声明性方法来进行此类对象转换:您正在转换JSON和POJO之间的结构。 杰克逊在这方面的支持受设计限制:两件事超出范围:验证(使用外部验证; Bean Validation API或JSON Schema验证器)和转换(可以使用JsonNode或外部库)。

答案 2 :(得分:0)

根据这种格式的稳定程度(以及你的QA家伙的心情),你可以在将Json传递给杰克逊之前直接改变它。这将修复被破坏的东西。 正则表达式是一个想法。在Hashmap中读取它,在那里移动值并将其作为另一个固定的Json写出来。但在伪代码中更简单:

String json = "...";
String lines = json.split( "\r" );
swap( lines[2], lines[3] ); //*1
String fixed = join( lines ); //*2

,其中

*1: tmp = lines[2]; lines[2] = lines[3]; lines[3] = tmp;
*2: http://stackoverflow.com/questions/1515437/java-function-for-arrays-like-phps-join

(如果我必须走这条路线,我会使用hashmap aproach)

答案 3 :(得分:-1)

您的患者被存储在患者对象之外。把它放进去,一切都很闪亮;)

如果你坚持把它放在json那里我恐怕你有麻烦了。 (最好的方法是说服Json设计师将它存储在Patient对象中,就像你在Java中一样。)

如果没有任何帮助,您必须使用数据传输对象(https://en.wikipedia.org/wiki/Data_transfer_object)或自定义反序列化器(Setting up JSON custom deserializer)才能在理智和疯狂的表示之间进行转换。