Java(或JVM平臺)的標準JSON庫,或者被稱爲「 Java的最佳JSON解析器」。html
Jackson提供了一套用於Java(和JVM平臺)的數據處理工具,包括旗艦級流JSON解析器/生成器庫,匹配的數據綁定庫(與JSON之間的POJO)和附加的數據格式模塊。以Avro, BSON, CBOR, CSV, Smile, (Java)Properties, Protobuf, XML 或YAML編碼的處理數據 ; 甚至還有大量的數據格式模塊,以支持普遍使用的數據類型的數據類型,例如 Guava, Joda, PCollections 等等。java
實際的核心組件位於他們本身的項目下-包括兩個核心軟件包: jackson-core、 jackson-databind。git
jackson-core項目包含Jackson數據處理器使用的抽象核心流式解析器和生成器,還包括處理JSON格式的解析器、生成器的默認實現。jackson-databind包含用於Jackson數據處理器的通用數據綁定功能和樹模型。它基於StreamingAPI(流解析器、生成器)包構建,並使用Jackson註釋進行配置。github
流式API是一套比較底層的API,速度快,可是使用起來特別麻煩。它主要是有兩個核心類,一個是JsonGenerator,用來生成json,另外一個是JsonParser,用來讀取json內容。
使用一般從建立可重用(而且在配置後是線程安全的)JsonFactory實例開始:spring
JsonFactory factory = new JsonFactory();
// 配置(若有必要):
factory.enable(JsonParser.Feature.ALLOW_COMMENTS);
// 另外,您也能夠方便地ObjectMapper(從Jackson-Databind軟件包中得到)。若是是這樣,您能夠執行如下操做:
JsonFactory factory = objectMapper.getFactory();
複製代碼
官方使用示例:Reading and Writing Event Streamsjson
JsonFactory f = mapper.getFactory();
// 也能夠直接構造 JsonFactory factory = new JsonFactory();
// 首先寫入
File jsonFile = new File("test.json");
JsonGenerator g = f.createGenerator(jsonFile);
// 寫入 JSON: { "message" : "Hello world!" }
g.writeStartObject();
g.writeStringField("message", "Hello world!");
g.writeEndObject();
g.close();
// 而後讀取
JsonParser p = f.createParser(jsonFile);
JsonToken t = p.nextToken();
t = p.nextToken();
if ((t != JsonToken.FIELD_NAME) || !"message".equals(p.getCurrentName())) {
// handle error
}
t = p.nextToken();
if (t != JsonToken.VALUE_STRING) {
// similarly
}
String msg = p.getText();
System.out.printf("My message to you is: %s!\n", msg);
p.close();
複製代碼
jackson-databind軟件包依賴於jackson-core和jackson-annotations軟件包,可是當使用Maven或Gradle之類的構建工具時,依賴項會自動包括在內。基本使用:後端
//建立一個com.fasterxml.jackson.databind.ObjectMapper用於全部數據綁定的實例,ObjectMapper是線程安全的,應該儘可能的重用。
ObjectMapper mapper = new ObjectMapper();
// 字符串反序列化爲對象
Grade grade = mapper.readValue(jsonStr, Grade.class);
// Jackson是基於JavaBean來序列化屬性的,屬性要有GETTER方法,纔會輸出該屬性
Map<String, ResultValue> results = mapper.readValue(jsonSource, new TypeReference<Map<String, ResultValue>>() { } );
// 對象序列號化爲json字符串
String gradeStr = mapper.writeValueAsString(grade);
// 對象序列號化爲byte數組
byte[] jsonBytes = mapper.writeValueAsBytes(grade);
// 寫入文件
mapper.writeValue(new File("result.json"), grade);
複製代碼
在調用了某個api後,須要解析返回的json數據獲取信息,這種狀況下爲json建立一個對應的類是很不方便的。此時使用Tree Model來解析json就比較方便了api
JsonNode root = mapper.readTree(rerenjson);
JsonNode user = root.get("user");
root.with("other").put("type", "student");
int id = user.get("id").asInt();
String name = user.get("name").asText();
JsonNode avators = user.get("avatar");
if (avators.isArray()) {
for (Iterator it = avators.getElements(); it.hasNext(); ){
JsonNode avator = it.next();
if ("tiny".equals(avator.get("type").asText())) {
String ava = avator.get("url").asText();
break;
}
}
}
複製代碼
Jackson的一項有用(但不是很廣爲人知)的功能是它可以進行任意的POJO到POJO轉換。通常作法,首先將POJO編寫爲JSON,其次將JSON綁定到另外一種POJO中。Jackson實現跳過JSON的實際生成,並使用更高效的中間實現。數組
// 基本使用
ResultType result = mapper.convertValue(sourceObject, ResultType.class);
// List<Integer> 轉 int[]
List<Integer> sourceList = ...;
int[] ints = mapper.convertValue(sourceList, int[].class);
// POJO 轉 Map!
Map<String,Object> propertyMap = mapper.convertValue(pojoValue, Map.class);
// POJO 轉 back
PojoType pojo = mapper.convertValue(propertyMap, PojoType.class);
// 解碼Base64!(缺省字節[]表示是base64編碼字串)
String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz";
byte[] binary = mapper.convertValue(base64, byte[].class);
複製代碼
一、經常使用註解:
@JsonIgnore 此註解用於屬性上,做用是進行JSON操做時忽略該屬性。
@JsonFormat 此註解用於屬性上,做用是把Date類型直接轉化爲想要的格式,如@JsonFormat(pattern = 「yyyy-MM-dd HH-mm-ss」)。
@JsonProperty 此註解用於屬性上,做用是把該屬性的名稱序列化爲另一個名稱,如把trueName屬性序列化爲name,@JsonProperty(「name」)。也能夠直接在類上添加註解 @JsonIgnoreProperties({ "a", "b" }),跳過a、b屬性。
@JsonCreator構造函數能夠是公共的,也能夠是私有的。Jackson不須要定義「默認構造函數」(不帶參數的構造函數)。安全
二、Mapper的一些實用配置:(其餘配置可見上述jackson-databind官方連接)
// (空對象是否拋出異常)
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// (日期改成時間戳)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// (特殊字符和打印符,這在FastJson曾是個bug)
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// (單引號)
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
複製代碼
SpringMVC內置json解析器就是Jackson,以SpringBoot技術棧開發的話,用默認的Jackson是最好的。
spring:
jackson:
# 設置屬性命名策略,對應jackson下PropertyNamingStrategy中的常量值,SNAKE_CASE-返回的json駝峯式轉下劃線,json body下劃線傳到後端自動轉駝峯式
property-naming-strategy: SNAKE_CASE
# 全局設置@JsonFormat的格式pattern
date-format: yyyy-MM-dd HH:mm:ss
# 當地時區
locale: zh
# 設置全局時區
time-zone: GMT+8
# 經常使用,全局設置pojo或被@JsonInclude註解的屬性的序列化方式
default-property-inclusion: NON_NULL #不爲空的屬性纔會序列化,具體屬性可看JsonInclude.Include
# 常規默認,枚舉類SerializationFeature中的枚舉屬性爲key,值爲boolean設置jackson序列化特性,具體key請看SerializationFeature源碼
serialization:
WRITE_DATES_AS_TIMESTAMPS: true # 返回的java.util.date轉換成timestamp
FAIL_ON_EMPTY_BEANS: true # 對象爲空時是否報錯,默認true
# 枚舉類DeserializationFeature中的枚舉屬性爲key,值爲boolean設置jackson反序列化特性,具體key請看DeserializationFeature源碼
deserialization:
# 經常使用,json中含pojo不存在屬性時是否失敗報錯,默認true
FAIL_ON_UNKNOWN_PROPERTIES: false
# 枚舉類MapperFeature中的枚舉屬性爲key,值爲boolean設置jackson ObjectMapper特性
# ObjectMapper在jackson中負責json的讀寫、json與pojo的互轉、json tree的互轉,具體特性請看MapperFeature,常規默認便可
mapper:
# 使用getter取代setter探測屬性,如類中含getName()但不包含name屬性與setName(),傳輸的vo json格式模板中依舊含name屬性
USE_GETTERS_AS_SETTERS: true #默認false
# 枚舉類JsonParser.Feature枚舉類中的枚舉屬性爲key,值爲boolean設置jackson JsonParser特性
# JsonParser在jackson中負責json內容的讀取,具體特性請看JsonParser.Feature,通常無需設置默認便可
parser:
ALLOW_SINGLE_QUOTES: true # 是否容許出現單引號,默認false
# 枚舉類JsonGenerator.Feature枚舉類中的枚舉屬性爲key,值爲boolean設置jackson JsonGenerator特性,通常無需設置默認便可
# JsonGenerator在jackson中負責編寫json內容,具體特性請看JsonGenerator.Feature
複製代碼
默認配置(配置文件配置JacksonAutoConfiguration)和用戶自定義Java代碼配置只須要一種便可。
jackson
jackson-core
jackson-databind 平時咱們使用最多的就是數據綁定吧,配置好以後真讓人省心,樹模型和類型轉換也能爲咱們的工做帶來便利,流式API平常使用不是太方便。但願這篇文章能對大家有幫助。歡迎你們一塊兒學習,有誤之處煩請你們指正。