Spring如何从JSON响应中过滤属性? [英] How to filter attributes from JSON response in spring?

查看:66
本文介绍了Spring如何从JSON响应中过滤属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似以下的控制器,

I have a controller like the following,

@RequestMapping(value = "rest/v1/tester")
public class TestController {

    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public ResponseEntity<SampleResults> search(@ModelAttribute("criteria")SampleCriteria criteria) throws Exception {
            SampleResults sampleResults = sampleService.search(criteria);
            return new ResponseEntity<>(sampleResults, OK);
    }

}

我有另一个这样的控制器,

I have another controller like so,

@RequestMapping(value = "rest/v1/second")
public class SecondTestController {

@RequestMapping(value = "/search", method = RequestMethod.GET)
    public ResponseEntity<SampleResults> search(@ModelAttribute("criteria")SampleCriteria criteria) throws Exception {
            SampleResults sampleResults = secondsampleService.search(criteria);
            return new ResponseEntity<>(sampleResults, OK);
    }

}

我的结果结构如下:

public class SampleResults extends Results<SearchSummary, Sample> {
}

这是从结果类扩展的:

public class Results<SUMMARY,RESULTS> {
    private SUMMARY summary;
    private List<RESULTS> results;

    /*Constructors, getters and setters*/
}

现在我要在结果字段中设置的模型是

Now the model that I am going to set into the results field is,

@JsonDeserialize(as = SampleImpl.class)
public interface Sample {

    Long getId();
    void setId(Long id);

    String getName();
    void setName(String name);

    int getAge();
    void setAge(int age);

}

public class SampleImpl implements Sample {

    private Long id;
    private String name;
    private int age;

    /* Getters and Setters */

}

现在对于上面提到的TestController,我想显示json响应中的所有字段,而在SecondTestController中,我想屏蔽(不显示)json响应中的age属性.我如何在春季实现这一目标.任何帮助,不胜感激!

Now for the TestController mentioned above, I would like to display all the fields in the json response, whereas in the SecondTestController I would like to mask (not show) the age attribute in the json response. How can I achieve this in spring. Any help greatly appreciated!

推荐答案

我认为最简单的方法是使用Jackson @JsonFilter(如果您希望动态的话).

I think the most simple way to do that is to use Jackson @JsonFilter if you want it dynamic.

例如,这里可能是Spring Boot的一个例子:

For instance, here could be an exemple with Spring Boot :

您的文档:

@JsonFilter("myFilter")
class Document {
   private field1;
   private field2;
}

修改默认配置的HttpMessageConverter:

Modify your default configured HttpMessageConverter :

@Configuration
class WebMvcConfiguration extends WebMvcConfigurationSupport {
    @Override
    protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for(HttpMessageConverter<?> converter: converters) {
            if(converter instanceof MappingJackson2HttpMessageConverter) {
                ObjectMapper mapper = ((MappingJackson2HttpMessageConverter)converter).getObjectMapper();
                mapper.setFilterProvider(new SimpleFilterProvider().addFilter("myFilter", SimpleBeanPropertyFilter.serializeAll()));
            }
        }
    }
}

此过滤器默认情况下将全部序列化.此步骤是强制性的,如果不指定它,将会出现一个例外,他不知道myFilter何时控制器将尝试生成对象响应.

This Filter will serialize all by default. This step is mandatory, if you don't specify it, you will have an exception coming that he does not know myFilter when your controller will try to generate an object response.

然后,在您的控制器中,这是序列化所有字段的常规端点(使用先前声明的过滤器):

Then, in you controller, here is your regular endpoint that serialize all field (using the previously declared filter):

@RequestMapping(value = "path/document", method = RequestMethod.GET)
public Document getDocumentWithAllFields() {
   return new Document("val1","val2");
} 
//result : {"field1":"val1","field2":"val2"}

现在,端点具有相同的对象,并且只序列化了一些字段:

And now, the endpoint to have the same object with only some fields serialized :

@RequestMapping(value = "path/document", method = RequestMethod.GET)
public MappingJacksonValue getDocumentWithSomeFields(@RequestParam String[] fields) {
    MappingJacksonValue wrapper = new MappingJacksonValue(new Document("val1","val2"));
    FilterProvider filterProvider = new SimpleFilterProvider().addFilter("myFilter", 
         SimpleBeanPropertyFilter.filterOutAllExcept(fields)); 
    wrapper.setFilters(filterProvider);
    return wrapper;
} 
//result : {"field1":"val1"} (with 'fields' being a coma separated list, containing here just "field1"

这篇关于Spring如何从JSON响应中过滤属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆