一、前言
把對象序列化為json字元串輸出的庫很多,本文我們來看如何基于jackson動态控制哪些屬性需要進行序列化。
二、序列化輸出方式
對應使用Jackson,需要我們在pom檔案中引入下面依賴:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.1</version>
</dependency>
首先簡單看下如何使用:
@Data
@JsonFilter("car")
static class Car {
private String brand;
private long price;
private int load;
private long id;
}
@Data
@JsonFilter("house")
static class House {
private String title;
private long price;
private long id;
}
@Data
@JsonFilter("person")
static class Person {
private Car car;
private House house;
private long weight;
private long id;
private String name;
}
public static Person makePerson() {
Person person = new Person();
person.setName("加多");
person.setWeight(150);
person.setId(8888);
House house = new House();
house.setId(234);
house.setTitle("杭州院子");
house.setPrice(10000000);
person.setHouse(house);
Car car = new Car();
car.setBrand("瑪莎拉蒂");
car.setId(123L);
car.setLoad(3);
car.setPrice(1000000);
person.setCar(car);
return person;
}
public static void main(String[] arg) throws JsonProcessingException {
//1.造人
Person person = makePerson();
//2.序列化為json字元串并輸出
ObjectMapper objectMapper = new ObjectMapper();
System.out.println(objectMapper.writeValueAsString(person));
}
如上代碼1,建立了一個Person類,代碼2建立ObjectMapper,并且調用其writeValueAsString方法,把Person對象序列化為字元串,然後列印輸出,結果為:
{
"car":{
"brand":"瑪莎拉蒂",
"price":1000000,
"load":3,
"id":123
},
"house":{
"title":"杭州院子",
"price":10000000,
"id":234
},
"weight":150,
"id":8888,
"name":"加多"
}
如上Person中所有屬性,包含其中Car中所有屬性,House的所屬性都輸出了。
如果我們不想序列化某個屬性,比如不想序列化Person中的Car中的price屬性,則我們隻需要在Car類屬性上加注解:@JsonIgnore:
@Data
static class Car {
private String brand;
@JsonIgnore
private long price;
...
}
同理如果不想要序列化Person中的car屬性,在其上添加 @JsonIgnore注解即可。
對應上面情況,我們隻能靜态的使用 @JsonIgnore注解來過濾不需要序列化的屬性,那麼有沒有辦法在運作時進行動态過濾不需要過濾的屬性那?其實注解 @JsonFilter,就可以做這個事件。
@Data
@JsonFilter("car")
static class Car {
...
}
@Data
@JsonFilter("house")
static class House {
...
}
@Data
@JsonFilter("person")
static class Person {
...
}
如上首先在所有類上加上對應的注解,然後通過下面代碼添加過濾器:
public static void main(String[] arg) throws JsonProcessingException {
//1.造人
Person person = makePerson();
//2.序列化為json字元串并輸出
ObjectMapper objectMapper = new ObjectMapper();
//2.1建立過濾器
SimpleFilterProvider filterProvider = new SimpleFilterProvider();
//2.1.1Person類的屬性過濾器(隻序列化car,house,name字段)
filterProvider.addFilter("person", SimpleBeanPropertyFilter.filterOutAllExcept(Sets.newHashSet("car", "house", "name")));
//2.1.2House類的屬性過濾器(隻序列化title,price字段)
filterProvider.addFilter("house", SimpleBeanPropertyFilter.filterOutAllExcept(Sets.newHashSet("title", "price")));
//2.1.3Car類的屬性過濾器(隻序列化brand字段)
filterProvider.addFilter("car", SimpleBeanPropertyFilter.filterOutAllExcept(Sets.newHashSet("brand")));
//2.2設定過濾器,并執行序列化
objectMapper.setFilterProvider(filterProvider);
System.out.println(objectMapper.writeValueAsString(person));
}
如上代碼通過2.1.1-2.1.3為Person,House,Car添加了屬性過濾器,隻序列化指定的字段,然後代碼2.2把過濾器設定到ObjectMapper對象裡面,最後執行序列化,運作上面代碼,輸出如下:
{
"car":{
"brand":"瑪莎拉蒂"
},
"house":{
"title":"杭州院子",
"price":10000000
},
"name":"加多"
}
可知序列化時,隻序列化了我們指定的字段。上面代碼隻是一個執行個體,在運作時,我們可以根據需要動态設定過濾器,來起到動态序列化指定字段的功能。
三、總結
本文我們談論了如何使用 @JsonFilter進行動态指定需要序列化字段的功能。
需要注意的是一旦一個類上加了 @JsonFilter注解,如果沒有指定過濾器,則運作時會報錯,那麼如何讓一個類即可以支援動态過濾,又在沒指定過濾器的情況下正常運作那?其實很簡單,我們可以自定義注解并注冊解析器...