Java объекты в JSON без ключа - PullRequest
0 голосов
/ 10 ноября 2018

Я лучше узнаю Джсона. Но у меня есть некоторые проблемы с этим. Я хочу создавать объекты JSON из классов Java. Я пытаюсь преобразовать 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;
    }
}

Мне нужен этот класс для идентификатора вложения.

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 и т. Д.? Я был бы очень рад, если бы кто-нибудь мог мне помочь.

Я имею в виду с ключом идентификаторы в массиве.

1 Ответ

0 голосов
/ 11 ноября 2018

Решение 1: Пользовательский сериализатор

Подробности: вы можете сказать Джексону, как сериализовать ваш объект. Если вы хотите сериализовать его всегда одним и тем же способом, вы можете указать на уровне класса, что он всегда должен использовать этот сериализатор. Если вы считаете, что вам понадобятся другие сериализаторы, вы должны вместо этого настроить свой objectMapper: ObjectMapper mapper = new 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, преимущество в том, что вам не нужен объект-оболочка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...