![](/img/trans.png)
[英]Bazel build with Jackson annotations for ser/Deser and generate Java classes
[英]Jackson Ser/Deser: Proxying an object to/from an id w/ a different key
提前致歉。 這似乎是一項簡單的任務,但數小時后在Google上進行了猜測/檢查,但我仍然無法弄清楚。
我正在為公司提供的API編寫Java便捷包裝器庫。 其中一個類如下所示:
class View extends Model<View>
{
List<Column> columns;
Column primaryColumn;
}
但是,我們的API實際上需要的是primaryColumnId
整數,而不是實際的Column
對象。 我想在庫中維護強類型化的getPrimaryColumn()
和setPrimaryColumn(Column)
以減少開發人員錯誤,但是我在編寫需要對/進行ser / deser的getter / setter之間的某種轉換時遇到了很大的困難從JSON。
我正在使用標准Bean序列化策略。 我想避免使用完全自定義的方法,因為實際上View
有很多領域。 到目前為止,這是我想出的。
我認為 (尚未測試)我可以通過創建一個自定義JsonSerializer
來處理序列化情況,該自定義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
,但是要注意在適當的地方屏蔽方法。
事實證明,由於傑克遜進行了令人討厭的反思,因此可以通過private
方法進行查看。 因此,把戲最終只是按照以下思路進行:
private void setPrimaryColumnId(Integer id) {...}
private Integer getPrimaryColumnId() {...}
public void setPrimaryColumn(Column column) {...}
@JsonIgnore
public Column getPrimaryColumn() {...}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.