【问题标题】:How to include attributed filtered with JsonFilter in spring controller?如何在 spring 控制器中包含使用 JsonFilter 过滤的属性?
【发布时间】:2016-11-22 13:11:32
【问题描述】:

我只需要在一个控制器中过滤某些属性。

Fasterxml JsonFilter 在我将它与控制器中的 ObjectMapper 一起使用时起作用,如下所示

FilterProvider filter2 = new SimpleFilterProvider().addFilter("somefilter",
SimpleBeanPropertyFilter.filterOutAllExcept("prop1","prop2"));

像对象一样

@JsonFilter("somefilter")
public class Bar{
String prop1;
String prop2;
String prop3;
}

但是当尝试使用 spring 控制器返回相同的对象时

 @RequestMapping(value = "/path", method = RequestMethod.GET)
    protected @ResponseBody Foo handleGet( .. 

在哪里

public class Foo{
Bar p1;
Bar p2;
}

Bar 属性被完全省略。在这种情况下,我们需要返回未过滤的对象。

我必须使用控制器中的对象映射器来返回整个对象。

有没有办法禁用控制器的过滤器?

【问题讨论】:

  • 您的意思是您要跳过 Bar 对象上的某些字段以进行序列化?
  • 是的,使用 ObjectMapper 时跳过序列化。但是序列化控制器中的所有内容。
  • 而当控制器使用它时,你想显示字段吗?抱歉,我无法编辑我之前的评论。
  • 你试过@JsonIgnoreProperties而不是过滤器吗?
  • 那是不同的。

标签: java spring spring-mvc jackson fasterxml


【解决方案1】:

您可以尝试MappingJacksonValue 设置 Jackson 过滤器提供程序以在 Spring 控制器中序列化 POJO。

来自AbstractJackson2HttpMessageConverter的源码:

protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException {
    ...
    try {
        ...
        if (object instanceof MappingJacksonValue) {
            MappingJacksonValue container = (MappingJacksonValue) object;
            ...
            filters = container.getFilters();
        }
        ...
        ObjectWriter objectWriter;
        if (serializationView != null) {
            objectWriter = this.objectMapper.writerWithView(serializationView);
        }
        else if (filters != null) {
            objectWriter = this.objectMapper.writer(filters);
        }
        else {
            objectWriter = this.objectMapper.writer();
        }
        ...
        objectWriter.writeValue(generator, value);
        ...
    }

应该可以通过MappingJacksonValue 中设置的过滤器重置objectMapper 中的FilterProvider。在您的情况下,您可以尝试以下操作:

@RequestMapping(value = "/foo", method = RequestMethod.GET)
protected @ResponseBody MappingJacksonValue handleGet(...) {
    MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(foo);    
    FilterProvider filter = new SimpleFilterProvider().addFilter("somefilter", SimpleBeanPropertyFilter.serializeAllExcept());
    mappingJacksonValue.setFilters(filter);
    return mappingJacksonValue;
}

如果您只有一个控制器需要过滤来自Bar 的属性,您也可以考虑为特定控制器添加过滤器,而不是将其设置到 ObjectMapper 中:

@RequestMapping(value = "/bar", method = RequestMethod.GET)
protected @ResponseBody MappingJacksonValue handleGet(...) {
    MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(bar);    
    FilterProvider filter = new SimpleFilterProvider().addFilter("somefilter", SimpleBeanPropertyFilter.filterOutAllExcept("prop1","prop2"));
    mappingJacksonValue.setFilters(filter);
    return mappingJacksonValue;
}

【讨论】:

    猜你喜欢
    • 2021-10-01
    • 1970-01-01
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 2021-08-22
    • 1970-01-01
    • 2012-12-27
    • 2011-07-26
    相关资源
    最近更新 更多