Десериализация суперкласса json для объекта подкласса - PullRequest
0 голосов
/ 31 октября 2018

Мое программное обеспечение вращается вокруг устройств RFID. Все эти устройства имеют (в основном) одинаковые параметры конфигурации, такие как то, при какой настройке мощности должны передаваться антенны. Однако API-интерфейсы, прилагаемые к каждому считывателю, различаются по настройке мощности антенны. Конфигурация считывателей выполняется на центральном сервере и сохраняется в виде строки json. Я пытаюсь найти способ иметь общую строку json для настройки мощности антенны (например) без необходимости настраивать ее для каждого API. Вот чего я пытаюсь достичь.

Строка json для настройки мощности антенны будет выглядеть примерно так:

{"power":30}

Мой суперкласс для настройки питания:

public abstract class SetPower<T> {
    protected int power;

    public SetPower(int power) {
        this.power = power;
    }

    public abstract void configure(T rfidReader);
}

Подкласс для настройки питания от считывателя CompanyX:

public class CompanyXSetPower extends SetPower<CompanyXReader> {

    @JsonCreator
    public CompanyXSetPower(@JsonProperty("power") int power) {
        super(power);
    }

    @Override
    public void configure(CompanyXReader reader) {
        reader.setPower((byte) power);
    }
}

Подкласс для настройки питания от считывателя CompanyY:

public class CompanyYSetPower extends SetPower<CompanyYReader> {

    @JsonCreator
    public CompanyYSetPower(@JsonProperty("power") int power) {
        super(power);
    }

    @Override
    public void configure(CompanyYReader reader) {
        reader.setOutputPower(power);
    }
}

Каков «лучший» способ десериализации универсального json в определенный подкласс без необходимости указывать подробности класса в строке json. Я согласен с включением деталей суперкласса в строку json, поскольку должен быть какой-то способ определения типа объекта, для которого предназначены данные json.

1 Ответ

0 голосов
/ 31 октября 2018

То, что вы хотите, называется десериализацией JSON в полиморфные типы. (см., например, этот вопрос для аналогичной проблемы).

Вам нужно будет добавить дополнительный атрибут типа к вашему содержимому JSON, так что, например, {"type":"x","power":30} десериализуется в CompanyXSetPower объект, и {"type":"y","power":30} становится десериализованным в CompanyYSetPower объект.

Чтобы это работало, вам нужно улучшить свой абстрактный базовый класс SetPower с помощью @JsonTypeInfo и @JsonSubTypes аннотации, так что Джексон будет достаточно информации о сопоставлении между JSON и вашими различными классами Java.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = CompanyXSetPower.class, name = "x"),
    @JsonSubTypes.Type(value = CompanyYSetPower.class, name = "y")
})
public abstract class SetPower<T> {
    protected int power;

    public SetPower(int power) {
        this.power = power;
    }

    public abstract void configure(T rfidReader);
}

Тогда десериализацию можно выполнить просто:

ObjectMapper objectMapper = new ObjectMapper();
SetPower<?> setPower = objectMapper.readValue(url, SetPower.class);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...