简体   繁体   中英

Lombok/Jackson - POJO for a json array

I have a json array that I need to receive(de-serialize) from a server and send (serialize) to another server:

Example:

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

I started with writing the following POJO to represent this Json array:

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


@Builder
@Value
public class Car {

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

With this:

  1. I am able to build the object using Lombok as:

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

  1. Unmarshal using something like unmarshal().json(Jackson, Car.class) .

While 1) and 2) work, they do NOT give me objects that actually represent the json example above.

They instead give this:

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

I tried using a parent class as below:

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

@Builder
@Value
public class Vehicle {

    private List<Car> vehicles;
}

But this also gives me a wrong object (notice the "vehicles" key Vs what I have in my above Example):

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

How can I write a POJO that represents this JSON array, preferably using Lombok? Or Jackson?

You don't need to wrap List<Car> in Vehicle class because Vehicle represents JsonObject and vehicles is a property in it. Just directly return or serialize the List<Car>

objectmapper.writeValueAsString(List<Car>);

Theres nothing to do with lombok for your problem, But I've managed to found a workaround for the question

Create a custom Serializer and 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;
    }
}

And after that configure ObjectMapper to use the 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));

You car read here more about what I did.

If you want to use the ObjectMapper also for your web requests and response serialization read that article

Just add it in a List

Like

List<Car> carList=new ArrayList<>();

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

carList.add(myCar);

you will get

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM