通过密钥名称解析Java中的JSON

时间:2018-12-12 11:46:39

标签: java json rest parsing jackson

我没有找到关于同一问题的任何话题。如果我错了请纠正我。

以下JSON是我从外部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 
            }
        }
    ]
}

因此,我得到了车辆列表,每个元素都是一个对象,该对象具有一个名为 car或Motorcycle的字段,没有其他选择。两种类型的车辆都具有完全相同的数据字段。 区分这两种类型的唯一方法是通过JSON中的键名

我要如何解析:

在Java中,我有三个对象:

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; }
}

是否可以获取每个实例均为汽车或摩托车的车辆列表?

3 个答案:

答案 0 :(得分:1)

我尝试的一种解决方案是使用一个中间类,该中间类将更多内容映射到json结构:

'hi'

使用Jackson ObjectMapper将json解析为此类:

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;
    }
}

最后的Vehicles变量包含Car和Motorcycle实例的列表。

ObjectMapper.readValue方法存在不同的风格。

最后一件事:使用过的Maven依赖项:

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();
    }
}

答案 1 :(得分:1)

是的,有可能。

如果您想要getCarList和getMotorCycleList之类的东西,它们在解析json后分别返回汽车列表和摩托车列表:

  • 使用com.google.gson.JsonParser解析JSON
  • 然后通过使用“车辆”作为属性名称来获取JsonArray。
  • 遍历数组,并检查数组元素是否具有名称为“ car”的成员。 因此,创建一个汽车或摩托车的实例,填充属性并将其添加到汽车或摩托车的相应列表中。

如果需要添加代码段,请告诉我。

答案 2 :(得分:0)

看起来与您的要求非常相似:一个超类和几个子类。 使用@JsonTypeInfo批注:https://www.baeldung.com/jackson-inheritance