【问题标题】:Parsing JSON in Java by the name of the key通过键名在 Java 中解析 JSON
【发布时间】:2018-12-12 11:46:39
【问题描述】:

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

以下 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 
            }
        }
    ]
}

所以我得到了一个车辆列表,每个元素都是一个对象,它有一个名为 either 汽车或摩托车的字段,没有其他选项是可能的。两种类型的车辆具有完全相同的数据字段。 区分这两种类型的唯一方法是通过 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; }
}

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

【问题讨论】:

标签: java json rest parsing jackson


【解决方案1】:

我尝试的一个解决方案是使用更多映射到 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;
    }
}

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

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

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

ObjectMapper.readValue 方法有不同的风格。

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

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

【讨论】:

  • 谢谢!进行一些重构以匹配我自己的数据结构并以不同的方式实现逻辑(没有内部类等)。完美运行!
【解决方案2】:

是的,这是可能的。

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

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

如果需要添加代码 sn-p,请告诉我。

【讨论】:

  • 感谢您的回答。这也肯定行得通。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多