jackson根據屬性名動態序列化物件欄位
在info上有篇文章講的是 《為什麼說 GraphQL 可以取代 REST API?》,裡面提到這樣一段:
如果我們要實現這種方式:GET /users/?fields=name,address&include=resumes,subscriptions.按須只返回相應的欄位值。
有幾個點要考慮,今天我們只說其中的一個東西,這個問題就是要根據指定屬性名來序列化物件的值。傳統的方法都是通過 annotations來實現,但是這種方式使用方式很死,有沒有一種方法可以不通過annotations來完成呢,那就是通過jackson的@JsonFilter和addMixIn()方法配合使用。下面我們一步步來完成這個功能。
第一步:我們須要定義一個實體類 User,它就是我們須要序列化的物件:
public class User {
private String firstName;
private String lastName;
private String name;
private Integer age;
//getter setter
}
第二步:我們來建立一個通用的@JsonFilter物件,注意這個類沒有任何屬性:
@JsonFilter("userFilter")
public class UserFilter {
}
第三步:通過ObjectMapper預設提供的FilterProvider的實現類SimpleFilterProvider來配置相關的資訊,並進行輸出結果:
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();
}
}
}
我們可以看到輸出的結果為:
{"firstName":"water","lastName":"lang","age":30}
明顯可以找到這個name這個欄位沒有被序列化出來。
如果我們要繼續讓這個序列化的欄位進行動態改變怎麼做呢?很簡單,我們只須要再建立一個filterProvider就行了,然後通過writer()方法配置進去就行了。
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();
}
}
}
輸出結果:
{"firstName":"water","lastName":"lang","age":30}
{"firstName":"water","name":"water lang"}
注意的是我們這裡沒有直接使用ObjectMapper來做而是使用的ObjectWriter類來實現。當jackson在2.x版本,官方推薦優先使用後者。還有一個就是ObjectMapper具體應該是單例還是物件池(比如apache的ObjectPool)還是每次建立一個在github有很多爭議。如果併發量不是很大的情況下可以使用單例,在併發量很大的情況下推薦使用物件池來實現。
https://stackoverflow.com/questions/3907929/should-i-declare-jacksons-objectmapper-as-a-static-field
相關文章
- 根據欄位查表名
- 根據欄位名查詢所有表
- go根據字元動態設定結構體欄位名--hprose rpc應用Go字元結構體ROSRPC
- Scala的類、屬性、物件欄位物件
- js記一個根據欄位排序物件函式JS排序物件函式
- SpringBoot中根據屬性動態註冊Spring BeanSpring BootBean
- MySQL8 根據某屬性查詢欄位排名由自定義變數到rank()的變動MySql變數
- mybatis動態呼叫表名和欄位名MyBatis
- 深入理解JavaScript類與物件:揭秘類欄位和靜態屬性的妙用,js靜態屬性和例項屬性JavaScript物件JS
- 陣列物件根據物件中指定的屬性去重?你知道多少陣列物件
- 根據介面動態修改應用底部選單欄
- list集合根據某欄位分組
- Scala類的屬性以及物件私有欄位物件
- Stream流根據屬性去重
- js物件陣列(JSON) 根據某個共同欄位 分組物件陣列JSON
- Jackson序列化日期型別的屬性型別
- SQL Server中根據某個欄位,ID欄位自動增長的實現SQLServer
- jQuery根據多個屬性匹配元素jQuery
- 根據欄位名等查詢SAP的表或結構(程式程式碼)
- C#通過反射獲取物件屬性,列印所有欄位屬性的值C#反射物件
- js陣列操作——物件陣列根據某個相同的欄位分組JS陣列物件
- 二維陣列根據欄位進行排序陣列排序
- 二維陣列根據某個欄位排序陣列排序
- jQuery根據表格欄位升序和降序詳解jQuery
- odoo欄位屬性列舉Odoo
- C#屬性與欄位C#
- jdk8 stream 根據屬性去重JDK
- 使用jackson序列化物件物件
- 根據包名,在指定空間中建立物件物件
- swift4.0 物件資料來源根據屬性分組,時間排序Swift物件排序
- JAVA裡List集合中的物件根據物件的某個屬性值降序或者升序排序Java物件排序
- c# 非靜態欄位、方法或屬性要求物件引用C#物件
- SqlServer根據特定欄位分組後,對需要欄位進行分組拼接SQLServer
- 根據不同欄位,升降序排列查詢結果
- PHP二維陣列根據某個欄位排序PHP陣列排序
- 【資料】Arraylist中根據指定元素屬性排序排序
- perl根據函式名動態呼叫函式
- 共有的表單欄位屬性