我急需幫助。我目前正在對Content API中的某個資源進行一些安全性限制,其中我需要:包括屬性,截斷屬性(如果它們是String.class),或者基於SecurityContext從序列化對象中移除屬性。自定義BeanPropertyFilter - 僅序列化字符串的一部分
我使用傑克遜作爲我的json序列化程序,並選擇使用BeanPropertyFilter來檢查每個屬性是否應該序列化。
現在,刪除和包含選項非常簡單,無論是否序列化bean。
但是truncate選項有點惡化。所以這裏是關於房產的序列化迄今爲止所做的。
@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider, BeanPropertyWriter writer) throws Exception {
switch (determineFilterAction(writer)) {
case INCLUDE_UNMODIFIED:
writer.serializeAsField(bean, jgen, provider);
break;
case INCLUDE_TRUNCATED:
Object value = writer.get(bean);
if (!(value instanceof String)) {
throw new UnsupportedOperationException("Annotation indicates truncate on " + writer.toString() + " which is not a string, but a " + value.getClass().getSimpleName() + " and is unsupported");
}
JsonSerializer oldSerialzer= writer.getSerializer();
writer.assignSerializer(new TruncateStringJsonSerializer());
writer.serializeAsField(bean, jgen, provider);
writer.assignSerializer(oldSerialzer);
break;
case REMOVE:
// do nothing
break;
}
}
問題是,有一個在BeanPropertyWriter.assignSerializer()方法保護,不會讓我在一個新的自定義序列轉換爲一個屬性。
是否有任何方法掛鉤並修改bean值?或者我將不得不重寫Factories和BeanPropertyWriter以覆蓋assignSerializer()方法(以避免序列化器守護)?
我不能用特殊的編寫器註釋我的屬性,因爲序列化對象不知道有關SecurityContext的任何內容,所以沒有辦法將securityContext注入到自定義序列化器中。
有沒有什麼辦法可以使這個截斷選項發生(而不會太過分)?
在此先感謝。
//最好的問候,馬丁。
UPDATE
基於StaxMan的回答,我已經更新,看起來像這樣的方法,它似乎工作。至少我所有的測試都能正確運行。將在開發應用程序服務器上進一步測試。
@Override
public void serializeAsField(Object bean, JsonGenerator jgen, SerializerProvider provider, BeanPropertyWriter writer) throws Exception {
switch (determineFilterAction(writer)) {
case INCLUDE_UNMODIFIED:
writer.serializeAsField(bean, jgen, provider);
break;
case INCLUDE_TRUNCATED:
Object value = writer.get(bean);
if (!(value instanceof String)) {
throw new UnsupportedOperationException("Annotation indicates truncate on " + writer.toString() + " which is not a string, but a " + value.getClass().getSimpleName() + " and is unsupported");
}
String valueString = (String) value;
jgen.writeFieldName(writer.getName());
jgen.writeString(StringUtils.abbreviate(valueString, MAX_LENGTH));
break;
case REMOVE:
// do nothing
break;
}
}
如果我可以覆蓋默認的BeanPropertyWriter,即傑克遜用我自己的方法初始化並註冊它,它可以覆蓋防止我切換出序列化程序的警衛。但我無法找到任何人如何做到這一點在網絡上。 (至少不是沒有實施自己的工廠提供商和自己的工廠)。我不太喜歡。 – 2014-10-08 09:30:08