您可能正在尋找的是Module。該文件說,Modules是
爲可與ObjectMappers進行註冊,以提供一個定義良好的擴展集默認功能擴展的簡單接口。
以下是你如何使用它們來完成你想要的東西的例子。請注意,還有其他方式可以實現這一點;這只是其中之一。
一個簡單的DTO,可用於指定的屬性進行過濾:
public class PropertyFilter {
public Class<?> classToFilter;
public Set<String> propertiesToIgnore = Collections.emptySet();
public PropertyFilter(Class<?> classToFilter, Set<String> propertiesToIgnore) {
this.classToFilter = classToFilter;
this.propertiesToIgnore = propertiesToIgnore;
}
}
過濾掉基於一些attribute
您在當前request
存儲屬性的自定義模塊。
public class MyModule extends Module {
@Override
public String getModuleName() {
return "Test Module";
}
@Override
public void setupModule(SetupContext context) {
context.addBeanSerializerModifier(new MySerializerModifier());
}
@Override
public Version version() {
// Modify if you need to.
return Version.unknownVersion();
}
public static class MySerializerModifier extends BeanSerializerModifier {
public BeanSerializerBuilder updateBuilder(SerializationConfig config,
BeanDescription beanDesc,
BeanSerializerBuilder builder) {
List<PropertyFilter> filters = (List<PropertyFilter>) RequestContextHolder.getRequestAttributes().getAttribute("filters", RequestAttributes.SCOPE_REQUEST);
PropertyFilter filter = getPropertyFilterForClass(filters, beanDesc.getBeanClass());
if(filter == null) {
return builder;
}
List<BeanPropertyWriter> propsToWrite = new ArrayList<BeanPropertyWriter>();
for(BeanPropertyWriter writer : builder.getProperties()) {
if(!filter.propertiesToIgnore.contains(writer.getName())) {
propsToWrite.add(writer);
}
}
builder.setProperties(propsToWrite);
return builder;
}
private PropertyFilter getPropertyFilterForClass(List<PropertyFilter> filters, Class<?> classToCheck) {
for(PropertyFilter f : filters) {
if(f.classToFilter.equals(classToCheck)) {
return f;
}
}
return null;
}
}
}
注意:有一個在BeanSerializerModifier類爲更適合用於改變屬性列表(根據文檔)一changeProperties
方法。因此,您可以將編寫在updateBuilder
中的代碼移至changeProperties
方法並進行相應的更改。
現在,您需要將您自己的module
與您的ObjectMapper一起註冊。您可以從您的應用程序上下文中獲取Jackson HTTP消息轉換器,並獲取其對象映射器。我假設你已經知道如何做到這一點,因爲你一直在處理懶惰初始化問題。
// Figure out a way to get the ObjectMapper.
MappingJackson2HttpMessageConverter converter = ... // get the jackson-mapper;
converter.getObjectMapper().registerModule(new MyModule())
然後你就完成了。如果要爲特定類型的對象自定義序列化,請爲其創建一個PropertyFilter
,並將其放在List
中,並將其作爲當前請求中的一個屬性提供。這只是一個簡單的例子。您可能需要稍微調整以適應您的需求。
在你的問題中,你似乎正在尋找一種方法來指定序列化對象本身的屬性 - 過濾器。在我看來,這應該避免,因爲要過濾的屬性列表不屬於您的實體。但是,如果您確實想要這樣做,請創建一個interface
,其中提供setters
和getters
作爲屬性列表。假設接口的名稱是CustomSerialized
然後,您可以修改MyModule
類以查找此接口的實例並相應地過濾掉這些屬性。
注意:您可能需要根據所使用庫的版本來調整/調整一些內容。