为RESTful服务实现动态过滤

在前一节中,我们进行了静态过滤。现在我们要转向动态过滤。

在动态过滤中,我们根据需要为不同的服务定义不同的过滤器。因此,存在动态过滤的概念。

假设有三个字段:姓名(name)、电话(phone)和工资(salary)。我们想要在第一个服务中发送姓名和工资,在第二个服务中发送姓名和电话。

但是,动态过滤存在一些限制。我们无法直接在bean中配置动态过滤器。我们需要在检索值的地方开始配置过滤器。为了实现动态过滤,我们使用一个名为MappingJacksonValue的类。如果我们查看该类的定义,我们会在其中找到filter方法的定义。

让我们看看如何在我们的项目中实现动态过滤。

在以下示例中,我们将为“/filtering”映射发送姓名和工资。

步骤1: 打开 FilteringController.java 文件。

步骤2: 创建MappingJacksonValue类的构造函数,并将一个bean(someBean)作为构造函数参数传递。我们想要为这个特定的bean创建一个Mapping Jackson值。

MappingJacksonValue mapping = new MappingJacksonValue (someBean);  

步骤3: 要配置过滤器,我们需要创建它们。要创建过滤器,声明类型为FilterProvider的本地变量filters。FilterProvider是一个抽象类。它有一个SingleFilterProvider方法的单一实现。调用addFilter()方法,该方法有两个参数String id和SimpleBeanPropretyFilter filter。

FilterProvider filters=new SimpleFilterProvider().addFilter("SomeBeanFilter", filter);  

步骤4: 调用SimpleBeanPropertyFilter类的静态方法filterOutAllExcept()。它会过滤响应中除我们指定的字段之外的所有字段。我们希望在响应中发送姓名和工资字段,因此我们指定了这两个字段。

SimpleBeanPropertyFilter filter=SimpleBeanPropertyFilter.filterOutAllExcept("name", "salary");  

步骤5: 配置过滤器。

mapping.setFilters(filters);  

步骤6: 不要返回someBean,而是返回mapping

return mapping;

步骤7: 我们已经返回了mapping,所以我们需要将方法的返回类型更改为MappingJacksonValue。

public MappingJacksonValue retrieveSomeBean()  
  
@RequestMapping("/filtering")  
public MappingJacksonValue retrieveSomeBean()  
{  
SomeBean someBean=new SomeBean("Amit", "9999999999","39000");  
//invoking static method filterOutAllExcept()  
SimpleBeanPropertyFilter filter=SimpleBeanPropertyFilter.filterOutAllExcept("name", "salary");  
//creating filter using FilterProvider class  
FilterProvider filters=new SimpleFilterProvider().addFilter("SomeBeanFilter",filter);  
//constructor of MappingJacksonValue class  that has bean as constructor argument  
MappingJacksonValue mapping = new MappingJacksonValue(someBean);  
//configuring filters  
mapping.setFilters(filters);  
return mapping;  
}  

记住:有效过滤器的列表应该在bean中定义。如果我们不这样做,它将会返回所有字段。

步骤8: 打开 SomeBean.java 文件并使用注解 @JsonFilter 定义一个过滤器。它用于类级别。它定义了一个过滤器名称,在JSON序列化中过滤掉属性。

@JsonFilter("SomeBeanFilter")  

SomeBean.java

package cn.javatiku.server.main.filtering;  
import com.fasterxml.jackson.annotation.JsonFilter;  
@JsonFilter("SomeBeanFilter")  
public class SomeBean   
{  
private  String name;  
private  String phone;  
//JsonIgnore indicates that the annotated method or field is to be ignored  
//@JsonIgnore  
private  String salary;  
//generating constructor  
public SomeBean(String name, String phone, String salary)   
{  
super();      
this.name = name;  
this.phone = phone;  
this.salary = salary;  
}  
public String getName()   
{  
return name;  
}  
public void setName(String name)   
{  
this.name = name;  
}  
public String getPhone()   
{  
return phone;  
}  
public void setPhone(String phone)   
{  
this.phone = phone;  
}  
public String getSalary()   
{  
return salary;  
}  
public void setSalary(String salary)   
{  
this.salary = salary;  
}  
}  

使用类似的方法,我们可以在第二个方法中实现动态过滤。在此方法中,我们将为“/filtering-list”映射返回姓名和电话字段。

步骤1: 在此方法中,首先将方法的返回类型更改为MappingJacksonValue。

步骤2: 创建SomeBean的列表。

List<SomeBean> list=Arrays.asList(new SomeBean("Saurabh", "8888888888","20000"), new SomeBean("Devesh", "1111111111","34000"));  

步骤3: 指定我们要在响应中发送的字段名。在我们的例子中,我们指定了姓名和电话。

SimpleBeanPropertyFilter filter=SimpleBeanPropertyFilter.filterOutAllExcept("name", "phone");  

步骤4: 将列表传递给MappingJacksonValue的构造函数。

步骤5: 返回mapping。

@RequestMapping("/filtering-list")  
public MappingJacksonValue retrieveListOfSomeBeans()  
{  
List<SomeBean> list=Arrays.asList(new SomeBean("Saurabh", "8888888888","20000"), new SomeBean("Devesh", "1111111111","34000"));  
//invoking static method filterOutAllExcept()  
SimpleBeanPropertyFilter filter=SimpleBeanPropertyFilter.filterOutAllExcept("name", "phone");  
FilterProvider filters=new SimpleFilterProvider().addFilter("SomeBeanFilter",filter);  
//constructor of MappingJacksonValue class that has list as constructor argument  
MappingJacksonValue mapping = new MappingJacksonValue(list);  
//configuring filter  
mapping.setFilters(filters);  
return mapping;  
}  

FilteringController.java

package cn.javatiku.server.main.filtering;  
import java.util.Arrays;  
import java.util.List;  
import org.springframework.http.converter.json.MappingJacksonValue;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;  
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;  
import com.fasterxml.jackson.databind.ser.FilterProvider;  
@RestController  
public class FilteringController   
{  
//returning a single bean as response  
//values to send name and salary                                                              
@RequestMapping("/filtering")  
public MappingJacksonValue retrieveSomeBean()  
{  
SomeBean someBean=new SomeBean("Amit", "9999999999","39000");  
//invoking static method filterOutAllExcept()  
SimpleBeanPropertyFilter filter=SimpleBeanPropertyFilter.filterOutAllExcept("name", "salary");  
//creating filter using FilterProvider class  
FilterProvider filters=new SimpleFilterProvider().addFilter("SomeBeanFilter",filter);  
//constructor of MappingJacksonValue class  that has bean as constructor argument  
MappingJacksonValue mapping = new MappingJacksonValue(someBean);  
//configuring filters  
mapping.setFilters(filters);  
return mapping;  
}  
//returning a list of SomeBeans as response  
//values to send name and phone  
@RequestMapping("/filtering-list")  
public MappingJacksonValue retrieveListOfSomeBeans()  
{  
List<SomeBean> list=Arrays.asList(new SomeBean("Saurabh", "8888888888","20000"), new SomeBean("Devesh", "1111111111","34000"));  
//invoking static method filterOutAllExcept()  
SimpleBeanPropertyFilter filter=SimpleBeanPropertyFilter.filterOutAllExcept("name", "phone");  
FilterProvider filters=new SimpleFilterProvider().addFilter("SomeBeanFilter",filter);  
//constructor of MappingJacksonValue class that has list as constructor argument  
MappingJacksonValue mapping = new MappingJacksonValue(list);  
//configuring filter  
mapping.setFilters(filters);  
return mapping;  
}  
}  

然后打开REST客户端Postman,发送一个GET请求,URI为http://localhost:8080/filtering。它会返回响应中的姓名和工资字段,如下图所示:

restful-web-services-dynamic-filtering.png

再次,发送一个GET请求,URI为http://localhost:8080/filtering-list。它会返回一个列表,其中包含姓名和电话字段,如下图所示。

restful-web-services-dynamic-filtering2.png

标签: spring, Spring教程, Spring语言学习, Spring框架, Spring框架教程, Spring框架高级教程, spring boot, spring boot入门教程, spring boot学习教程, spring boot下载, spring boot框架入门, spring boot面试题, spring boot笔试题, spring boot学习指南, spring boot技术