Reputation: 35
I didn't find any topics on the same problem. Correct me if I am wrong.
The following JSON is the simplified version of the response I get back from an external API:
{
"vehicles": [
{
"car": {
"color": "blue",
"brand": "audi",
"maxSpeed": 300,
"releaseYear": 2016
}
},
{
"car": {
"color": "red",
"brand": "bmw",
"maxSpeed": 200,
"releaseYear": 2012
}
},
{
"motorcycle": {
"color": "yellow",
"brand": "yamaha",
"maxSpeed": 300,
"releaseYear": 2013
}
}
]
}
So I get a list of vehicles and each element is an object that has one field named either car or motorcycle, no other options are possible. Both types of vehicles have exactly the same data fields . The only way to differentiate both types is by the name of the key in JSON
How I want to parse it:
In Java I have three objects:
abstract class Vehicle {
String color;
String brand;
Integer maxSpeed;
Integer releaseYear
public boolean hasFourWheels();
}
class Car extends Vehicle {
public boolean hasFourWheels() { return true; }
}
class Motorcycle extends Vehicle {
public boolean hasFourWheels() { return false; }
}
Is it possible to get a list of Vehicles where each instance is either Car or Motorcycle?
Upvotes: 0
Views: 317
Reputation: 375
Yes, it is possible.
In case you want something like getCarList and getMotorCycleList which return you list of car and list of motorcycle respectively after parsing the json:
Let me know in case code snippet needs to be added.
Upvotes: 1
Reputation: 1932
Looks very similar to what you asking: one superclass and a couple of subclasses.
Use @JsonTypeInfo
annotation: https://www.baeldung.com/jackson-inheritance
Upvotes: 0
Reputation: 4475
A solution I tried is using an intermediate class which maps more to the json structure:
import java.util.ArrayList;
import java.util.List;
import cars.Car;
import cars.Motorcycle;
import cars.Vehicle;
public class VehiclesHolder {
List<VehicleHolder> vehicles=new ArrayList<>();
public static class VehicleHolder {
Car car;
Motorcycle motorcycle;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public Motorcycle getMotorcycle() {
return motorcycle;
}
public void setMotorcycle(Motorcycle motorcycle) {
this.motorcycle = motorcycle;
}
}
public List<VehicleHolder> getVehiclesHolder() {
return vehicles;
}
public void setVehiclesHolder(List<VehicleHolder> vehicles) {
this.vehicles = vehicles;
}
public List<Vehicle> getVehicles()
{
List<Vehicle> result=new ArrayList<Vehicle>();
for(VehicleHolder holder:vehicles)
{
result.add(holder.getCar()!=null?holder.getCar():holder.getMotorcycle());
}
return result;
}
}
Use Jackson ObjectMapper to parse json to this class:
import java.io.IOException;
import java.util.List;
import cars.Vehicle;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ParserMain {
public static void main(String[] args) throws IOException {
ObjectMapper objectMapper = new ObjectMapper();
VehiclesHolder holder=objectMapper.readValue(ParserMain.class.getResourceAsStream("input.json"), VehiclesHolder.class);
List<Vehicle> vehicles=holder.getVehicles();
}
}
The vehicles variable at the end contains a list of Car and Motorcycle instances.
The ObjectMapper.readValue method exists in different flavours.
Last thing: maven dependencies used:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
Upvotes: 1