Джексон Сер / Дезер: Проксирование объекта с / с идентификатором с другим ключом - PullRequest
0 голосов
/ 01 сентября 2011

Извиняюсь заранее. Это кажется простой задачей, но через несколько часов в Google и с предположением / проверкой я все еще не могу понять это.

Я пишу библиотеку удобных оболочек Java для API, предоставляемого моей компанией. Один из классов выглядит примерно так:

class View extends Model<View>
{
    List<Column> columns;
    Column primaryColumn;
}

Однако наш API на самом деле хочет primaryColumnId целое число, а не фактический Column объект. Я хочу сохранить строго типизированные getPrimaryColumn() и setPrimaryColumn(Column) в библиотеке, чтобы уменьшить ошибку разработчика, но у меня возникают значительные трудности при написании какого-то перевода между геттером / сеттером, который нам нужен для отправки / отправки в / из JSON.

Я использую стандартную стратегию сериализации Бина. Я хотел бы избежать полностью индивидуального подхода, потому что в действительности View имеет десятки полей. Вот что я понял до сих пор.

Я думаю (еще не тестировал), что я могу справиться с делом сериализация , просто создав пользовательский JsonSerializer, который выглядит примерно так:

public static class ColumnIdSerializer extends JsonSerializer<Column>
    {
        @Override
        public void serialize(Column column, JsonGenerator jsonGenerator,
                              SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeFieldName("primaryColumnId");
            jsonGenerator.writeNumber(column.id);
        }
    }

И затем присвоение аннотации соответствующему месту:

@JsonSerialize(using = Column.ColumnIdSerializer.class)
public Column getPrimaryColumn() { /* ... */ }

Это позволяет мне сериализовать id, а не весь класс, и переименовать ключ с primaryColumn на primaryColumnId.

Теперь мы переходим к десериализации . Здесь я сталкиваюсь с тремя проблемами.

Во-первых, чтобы успешно десериализовать столбец из идентификатора, мы должны сначала получить список столбцов. Это разрешимо, используя @JsonPropertyOrder в классе. Отлично, все готово.

Во-вторых, мне нужно сказать Джексону искать значение в primaryColumnId, а не primaryColumn. Я не знаю, как это сделать; JsonDeserializer, кажется, запускает после , ключ уже был найден, поэтому слишком поздно изменять его. JsonSchema похоже, что это может быть актуально, но я не могу найти никакой документации или интернет-болтовни о том, как использовать .

Третий - то, что из пользовательского класса JsonDeserializer я должен иметь возможность ссылаться на View, который десериализован, чтобы запросить у него Column взамен моего id int. Кажется, нет способа сделать это.

Должен ли я просто пропустить и добавить публичные getPrimaryColumnId() и setPrimaryColumnId(Integer), или есть способ преодолеть эти препятствия?

Ответы [ 2 ]

1 голос
/ 01 сентября 2011

Итак, я бы предложил что-то вроде этого:

class CustomView
{
    private final View parent;
    public CustomView(View view){
        parent = view;
    }

    // Jackson needs a no-arg constructor
    public CustomView(){
        parent = new View();
    }

    // ...
    public List<Columns> getColumns(){ ... }
    public void setColumns(List<Columns> columns){ ... }

    public int getPrimaryColumn(){
        return parent.getPrimaryColumn().getColumnId();
    }
    public void setPrimaryColumn(int column){
        parent.getPrimaryColumn().setColumnId(column);
    }
    //...

    // don't use `get` in the method name here to avoid serialization
    public View rawView(){
        return parent;
    }
}

При необходимости это можно записать как расширение View, но будьте осторожны, чтобы маскировать методы там, где это необходимо.

0 голосов
/ 08 сентября 2011

Оказывается, что, поскольку Джексон делает отвратительное отражение, он может видеть через private методы. Таким образом, трюк в конечном итоге заключался в следующем:

private void setPrimaryColumnId(Integer id) {...}

private Integer getPrimaryColumnId() {...}

public void setPrimaryColumn(Column column) {...}

@JsonIgnore
public Column getPrimaryColumn() {...}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...