Java对象到JSON无需密钥

时间:2018-11-09 21:33:12

标签: java json jackson

我越来越了解json。但是我有一些问题。我想从Java类创建JSON对象。 我正在尝试通过杰克逊将Java对象转换为JSON。

我想要的是:

{
    "id" : "005be2f0",
    "attachments":
    [
        {"id":"Y98-8370"},  
        {"id":"Y98-8371"},  
        {"id":"Y98-8372"},  

        {"filename" : "DummyDoc", "filetype" : "pdf"}
    ]
}

但是我在以下课程中得到的是:

{
  "id" : "005be2f0",
  "attachments" : [ {
    "id" : 
    [ 
        {"id":"Y98-8370"},  
        {"id":"Y98-8371"},  
        {"id":"Y98-8372"},  
    ],
    "filename" : "DummyDoc",
    "filetype" : "pdf"
  } ]
}

这是我的课程:

public class Attachment {
    @JsonPropertyOrder({ "id", "filename", "filetype" })
    public class Attachment {

    @JsonProperty("id")
    private List<AttachmentID> id = new ArrayList<>();

    @JsonProperty("filename")
    private String filename;

    @JsonProperty("filetype")
    private String filetype;

    public List<AttachmentID> getId() {
        return id;
    }

    public void setId(List<AttachmentID> id) {
        this.id = id;
    }

    public String getFilename() {
        return filename;
    }

    public void setFilename(String filename) {
        this.filename = filename;
    }

    public String getFiletype() {
        return filetype;
    }

    public void setFiletype(String filetype) {
        this.filetype = filetype;
    }
}

我需要此类作为附件的ID。

public class AttachmentID {

    @JsonProperty("id")
    private String id;

    public AttachmentID(String attachmentID) {
        this.id = attachmentID;
    }

    public AttachmentID() {
        // TODO Auto-generated constructor stub
    }

    @JsonProperty("id")
    public String getAttachmentID() {
        return id;
    }

    @JsonProperty("id")
    public void setAttachmentID(String attachmentID) {
        this.id = attachmentID;
    }
}

还有我的RecordAttachment类。

    @JsonPropertyOrder({ "id", "attachments" })
public class RecordAttachment {

    @JsonProperty("id")
    private String id;

    @JsonProperty("attachments")
    private List<Attachment> attachments = null;

    @JsonProperty("id")
    public String getId() {
        return id;
    }

    @JsonProperty("id")
    public void setId(String id) {
        this.id = id;
    }

    @JsonProperty("attachments")
    public List<Attachment> getAttachments() {
        return attachments;
    }

    @JsonProperty("attachments")
    public void setAttachments(List<Attachment> attachments) {
        this.attachments = attachments;
    }
}

有可能吗?
这与JsonNode,ObjectNode等有关吗? 如果有人可以帮助我,我将非常高兴。

我的意思是用键表示数组中的ID。

1 个答案:

答案 0 :(得分:0)

解决方案1:自定义序列化程序

详细信息:您可以告诉杰克逊如何序列化对象。如果要始终以相同的方式对其进行序列化,则可以在类级别指定它应始终使用此序列化器。如果您认为还需要其他序列化器,则应该自定义objectMapper:      ObjectMapper映射器=新的ObjectMapper();

 SimpleModule module = new SimpleModule();
 module.addSerializer(Attachment.class, new AttachmentSerializer());

附件序列化器:

public class AttachmentSerializer extends StdSerializer<Attachment> {

    public AttachmentSerializer() {
        this(null);
    }

    public AttachmentSerializer(Class<Attachment> t) {
        super(t);
    }

    @Override
    public void serialize(
            Attachment attachment, JsonGenerator jgen, SerializerProvider provider)
            throws IOException, JsonProcessingException {

        jgen.writeStartObject();
        jgen.writeArrayFieldStart("attachments");
        for (AttachmentID attachmentID : attachment.getId()) {
            jgen.writeStartObject();
            jgen.writeStringField("id", attachmentID.getAttachmentID());
            jgen.writeEndObject();
        }
        jgen.writeStartObject();
        jgen.writeStringField("filename", attachment.getFilename());
        jgen.writeStringField("filetype", attachment.getFiletype());

        jgen.writeEndObject();
        jgen.writeEndArray();
        jgen.writeEndObject();
    }
}

并添加:

@JsonSerialize(using = AttachmentSerializer.class)
@JsonPropertyOrder({"id", "filename", "filetype"})
public class Attachment {

我只是在您的Attachment类上添加了自定义序列化程序,因为它是唯一需要特殊处理的序列化程序。

解决方案2:使用所需的目标字段创建一个自定义的RecordAttachmentDTO,并将其序列化,而不是RecordAttachment。

public class RecordAttachmentDTO {
    private String id;
    private List<Map<String, String>> attachments = new ArrayList<>();

    public RecordAttachmentDTO(RecordAttachment recordAttachment) {
        this.id = recordAttachment.getId();
        List<Attachment> attachments = recordAttachment.getAttachments();
        attachments.forEach(attachment -> addAttachment(attachment));

    }

    private void addAttachment(Attachment attachment) {
        attachment.getId().forEach(attachmentID -> attachments.add(Collections.singletonMap("id", attachmentID.getAttachmentID())));
        Map<String, String> fileMap = new HashMap<>();
        fileMap.put("filename", attachment.getFilename());
        fileMap.put("fileType", attachment.getFiletype());
        attachments.add(fileMap);
    }

    public List<Map<String, String>> getAttachments() {
        return attachments;
    }

    public void setAttachments(List<Map<String, String>> attachments) {
        this.attachments = attachments;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }
}

如果需要,此解决方案将帮助您拥有多个串行器。该解决方案基本上是原始对象的包装。不是序列化原始对象,而是序列化包装器。

解决方案3:构建JsonNode对象

public static String serializeRecordAttachment(RecordAttachment recordAttachment) throws JsonProcessingException {
    ObjectMapper objectMapper = new ObjectMapper();
    ObjectNode recordNode = objectMapper.createObjectNode();
    recordNode.put("id", recordAttachment.getId());
    List<Attachment> attachments = recordAttachment.getAttachments();
    recordNode.set("attachments", 
    createAttachmentNode(objectMapper,attachments));
    return objectMapper.writeValueAsString(recordNode.toString);
}

private static ArrayNode createAttachmentNode(ObjectMapper objectMapper, List<Attachment> attachments) {
    ArrayNode attachmentsNode = objectMapper.createArrayNode();
    attachments.forEach(attachment -> addAttachment(objectMapper, attachmentsNode, attachment);
    return attachmentsNode;
}

private static void addAttachment(ObjectMapper objectMapper, ArrayNode attachmentsNode, Attachment attachment) {
    attachment.getId().forEach(idField -> {
        ObjectNode attchIdNode = objectMapper.createObjectNode();
        attchIdNode.put("id", idField.getAttachmentID());
        attachmentsNode.add(attchIdNode);
    });
    ObjectNode fileNode = objectMapper.createObjectNode();
    fileNode.put("filename", attachment.getFilename());
    fileNode.put("filetype", attachment.getFiletype());
    attachmentsNode.add(fileNode);
}

此解决方案与解决方案2类似,优点是您不需要包装对象。