提前道歉。这似乎是一个简单的任务,但几个小时后谷歌和猜/检查,我仍然无法弄明白。
我正在为我公司提供的API编写Java便捷包装器库。其中一个类看起来像这样:
class View extends Model<View>
{
List<Column> columns;
Column primaryColumn;
}
但是,我们的API实际上需要primaryColumnId
整数,而不是实际的Column
对象。我想在库中维护强类型getPrimaryColumn()
和setPrimaryColumn(Column)
以减少开发人员错误,但是我在我们需要ser /的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
在类上解决。好的,已经完成了。
第二个是我需要告诉杰克逊在primaryColumnId
而不是primaryColumn
下查看价值。我不知道该怎么做;在找到密钥后,JsonDeserializer
似乎会启动,因此修改它为时已晚。 JsonSchema
看起来可能有用,但我找不到任何关于如何使用的文档或网络聊天。
第三个是来自自定义JsonDeserializer
课程,我必须能够引用要反序列化的View
才能要求Column
以换取我的id
getPrimaryColumnId()
int。似乎没有办法做到这一点。
我是否应该沉迷并添加公开setPrimaryColumnId(Integer)
和{{1}},还是有办法克服这些障碍?
答案 0 :(得分:1)
所以我建议这样的事情:
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
,但请注意在适当的时候屏蔽方法。
答案 1 :(得分:0)
事实证明,由于杰克逊做了讨厌的反思,它可以通过private
方法看到。所以,这个伎俩最终只是按照以下方式:
private void setPrimaryColumnId(Integer id) {...}
private Integer getPrimaryColumnId() {...}
public void setPrimaryColumn(Column column) {...}
@JsonIgnore
public Column getPrimaryColumn() {...}