在info上有篇文章講的是 《為什么說 GraphQL 可以取代 REST API?》,里面提到這樣一段:

如果我們要實(shí)現(xiàn)這種方式:GET /users/?fields=name,address&include=resumes,subscriptions.按須只返回相應(yīng)的字段值。
有幾個(gè)點(diǎn)要考慮,今天我們只說其中的一個(gè)東西,這個(gè)問題就是要根據(jù)指定屬性名來序列化對(duì)象的值。傳統(tǒng)的方法都是通過 annotations來實(shí)現(xiàn),但是這種方式使用方式很死,有沒有一種方法可以不通過annotations來完成呢,那就是通過jackson的@JsonFilter和addMixIn()方法配合使用。下面我們一步步來完成這個(gè)功能。
第一步:我們須要定義一個(gè)實(shí)體類 User,它就是我們須要序列化的對(duì)象:
public class User {
private String firstName;
private String lastName;
private String name;
private Integer age;
//getter setter
}
第二步:我們來創(chuàng)建一個(gè)通用的@JsonFilter對(duì)象,注意這個(gè)類沒有任何屬性:
@JsonFilter("userFilter")
public class UserFilter {
}
第三步:通過ObjectMapper默認(rèn)提供的FilterProvider的實(shí)現(xiàn)類SimpleFilterProvider來配置相關(guān)的信息,并進(jìn)行輸出結(jié)果:
public class AppendTest {
public static void main(String[] args) {
User user = new User();
user.setFirstName("water");
user.setLastName("lang");
user.setName("water lang");
user.setAge(30);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(
Object.class, UserFilter.class);
FilterProvider filters = new SimpleFilterProvider()
.addFilter("userFilter",
SimpleBeanPropertyFilter.serializeAllExcept(
"name"));
ObjectWriter writer = objectMapper.writer(filters);
try {
System.out.println(writer.writeValueAsString(user));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
我們可以看到輸出的結(jié)果為:
{"firstName":"water","lastName":"lang","age":30}
明顯可以找到這個(gè)name這個(gè)字段沒有被序列化出來。
如果我們要繼續(xù)讓這個(gè)序列化的字段進(jìn)行動(dòng)態(tài)改變?cè)趺醋瞿??很簡單,我們只須要再?chuàng)建一個(gè)filterProvider就行了,然后通過writer()方法配置進(jìn)去就行了。
package com.github.bohnman.squiggly.examples.springboot.test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.jackson.databind.ser.FilterProvider;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.github.bohnman.squiggly.examples.springboot.model.User;
public class AppendTest {
public static void main(String[] args) {
User user = new User();
user.setFirstName("water");
user.setLastName("lang");
user.setName("water lang");
user.setAge(30);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.addMixIn(
Object.class, UserFilter.class);
FilterProvider filters = new SimpleFilterProvider()
.addFilter("userFilter",
SimpleBeanPropertyFilter.serializeAllExcept(
"name"));
ObjectWriter writer = objectMapper.writer(filters);
try {
System.out.println(writer.writeValueAsString(user));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
FilterProvider ageFilter = new SimpleFilterProvider()
.addFilter("userFilter",
SimpleBeanPropertyFilter.serializeAllExcept(
"age","lastName"));
ObjectWriter writer1 = objectMapper.writer(ageFilter);
try {
System.out.println(writer1.writeValueAsString(user));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
輸出結(jié)果:
{"firstName":"water","lastName":"lang","age":30}
{"firstName":"water","name":"water lang"}
注意的是我們這里沒有直接使用ObjectMapper來做而是使用的ObjectWriter類來實(shí)現(xiàn)。當(dāng)jackson在2.x版本,官方推薦優(yōu)先使用后者。還有一個(gè)就是ObjectMapper具體應(yīng)該是單例還是對(duì)象池(比如apache的ObjectPool)還是每次創(chuàng)建一個(gè)在github有很多爭議。如果并發(fā)量不是很大的情況下可以使用單例,在并發(fā)量很大的情況下推薦使用對(duì)象池來實(shí)現(xiàn)。
https://stackoverflow.com/questions/3907929/should-i-declare-jacksons-objectmapper-as-a-static-field