提前致歉。这似乎是一项简单的任务,但数小时后在Google上进行了猜测/检查,但我仍然无法弄清楚。
我正在为公司提供的API编写Java便捷包装器库。其中一个类如下所示:
class View extends Model<View>
{
List<Column> columns;
Column primaryColumn;
}
但是,我们的API实际上需要一个
primaryColumnId
整数,而不是实际的Column
对象。我想在库中维护强类型的getPrimaryColumn()
和setPrimaryColumn(Column)
以减少开发人员错误,但是我很难在我们需要从/从/从到的getter / setter之间编写某种转换。 JSON。我正在使用标准Bean序列化策略。我想避免使用完全自定义的方法,因为实际上
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
。现在,我们开始进行反序列化。在这里,我遇到三个问题。
首先是为了成功从ID反序列化列,我们必须首先具有列列表。使用类上的
@JsonPropertyOrder
可以解决此问题。太好了!第二个是我需要告诉Jackson在
primaryColumnId
下而不是primaryColumn
下查找值。我不知道该怎么做; JsonDeserializer
似乎在找到密钥后即刻启动,因此修改它为时已晚。 JsonSchema
看起来可能很相关,但是我找不到任何文档或有关如何使用它的互联网信息。第三个是,在自定义
JsonDeserializer
类中,我将必须能够引用要反序列化的View
,以便为它提供一个Column
来代替我的id
int。似乎没有办法做到这一点。我应该只是添加一个公共的
getPrimaryColumnId()
和setPrimaryColumnId(Integer)
,还是有办法克服这些障碍? 最佳答案
所以我建议这样的事情:
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
的方法,但是要注意在适当的地方屏蔽方法。