Ломбок / Джексон - POJO для массива json - PullRequest
1 голос
/ 20 февраля 2020

У меня есть массив json, который мне нужно получить (десериализовать) с сервера и отправить (сериализовать) на другой сервер:

Пример:

[
  {
    "car-name": "string",
    "parts": [
      "engine",
      "wheels"
    ]
  }
]

Я начал с написания следующего POJO для представления этого Json массива:

import lombok.Builder;
import lombok.Singular;
import lombok.Value;


@Builder
@Value
public class Car {

    private String carName;
    @Singular("part")
    private List<String> parts;
}

С этим:

  1. Я могу построить объект, используя Lombok как:

Car myCar = Car.builder().carName("Tesla").part("engine").part("wheels").build();

Unmarshal, используя что-то вроде unmarshal().json(Jackson, Car.class).

Хотя 1) и 2) работают, они НЕ дают мне объекты, которые на самом деле представляют пример json выше.

Вместо этого они дают следующее:

  {
    "car-name": "string",
    "parts": [
      "engine",
      "wheels"
    ]
  }

Я попытался использовать родительский класс, как показано ниже:

import lombok.Builder;
import lombok.Singular;
import lombok.Value;

@Builder
@Value
public class Vehicle {

    private List<Car> vehicles;
}

Но это также дает мне неправильный объект (обратите внимание на " ключи от транспортных средств по сравнению с тем, что у меня есть в моем примере выше):

  {
    "vehicles": {
        "car-name": "string",
        "parts": [
             "engine",
             "wheels"
             ]
        }
}

Как я могу написать POJO, который представляет этот массив JSON, предпочтительно с использованием Lombok? Или Джексон?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2020

Нет ничего общего с lombok для вашей проблемы, но мне удалось найти обходной путь для вопроса

Создание собственного Serializer и SerializerModifier

Car Serializer

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;

public class CarSerializer extends StdSerializer<Car> {
    private JsonSerializer<Object> defaultSerializer = null;

    public CarSerializer(JsonSerializer<Object> defaultSerializer) {
        super(Car.class);
        this.defaultSerializer = defaultSerializer;
    }

    public CarSerializer() {
        super(Car.class);
    }

    @Override
    public void serialize(Car value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
        jgen.writeStartArray();

        defaultSerializer.serialize(value, jgen, provider);

        jgen.writeEndArray();
    }
}

CarSerializerModifier

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

public class CarSerializerModifier extends BeanSerializerModifier {

    @Override
    public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {

        if (beanDesc.getBeanClass().equals(Car.class)) {
            return new CarSerializer((JsonSerializer<Object>) serializer);
        }

        return serializer;
    }
}

И после этого настройте ObjectMapper для использования CarSerializerModifier

Car myCar = Car.builder().carName("Tesla").part("engine").part("wheels").build();

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.setSerializerModifier(new CarSerializerModifier());
mapper.registerModule(module);

log.info(mapper.writeValueAsString(myCar));

Ваш автомобиль прочитайте здесь подробнее о том, что я сделал.

Если вы хотите использовать ObjectMapper также для ваших веб-запросов и сериализации ответов, прочитайте эту статью

0 голосов
/ 20 февраля 2020

Вам не нужно переносить List<Car> в Vehicle классе, потому что Vehicle представляет JsonObject, а vehicles является его свойством. Просто верните или сериализуйте List<Car>

objectmapper.writeValueAsString(List<Car>);
...