今天在其他項目里面看到有人用jackson,就試著用了一下切距,并做點筆記趾徽。
一奶陈、jackson簡介
解析原理:基于事件驅動,與GSON相同附较,先創(chuàng)建一個對應于JSON數(shù)據(jù)的JavaBean類就可以通過簡單的操作解析出所需JSON數(shù)據(jù)吃粒。但和Gson解析不同的是,GSON可按需解析拒课,即創(chuàng)建的JavaBean類不一定完全涵蓋所要解析的JSON數(shù)據(jù)徐勃,按需創(chuàng)建屬性事示,但Jackson解析對應的JavaBean必須把Json數(shù)據(jù)里面的所有key都有所對應,即必須把JSON內的數(shù)據(jù)所有解析出來僻肖,無法按需解析肖爵。但Jackson的解析速度和效率都要比GSON高
二、Jackson臀脏、JSON-lib劝堪、Gson的比較
網(wǎng)上偷來一張圖作為對比Jackson、JSON-lib揉稚、Gson的解析速率
測試總結:
1秒啦、顯而易見,無論是哪種形式的轉換搀玖,Jackson > Gson > Json-lib余境。
Jackson的處理能力甚至高出Json-lib有10倍左右
2、JSON-lib似乎已經停止更新灌诅,最新的版本也是基于JDK15芳来,而Jackson的社區(qū)則較為活躍;
3猜拾、在測試性能的同時即舌,又以人肉方式對這三個類庫轉換的正確性 進行了檢查 ,三者均達100%正確 挎袜;
4侥涵、JSON-lib在轉換諸如Date類型時較為累贅,如以下是兩者的轉換結果:
JSON-lib:
{"brithday":{"date":17,"day":2,"hours":9,"minutes":24,"month":7,"seconds":26,"time":1282008266398,"timezoneOffset":-480,"year":110}}
Jackson:
{"brithday":1282008123101}
5宋雏、JSON-lib依賴commons系列的包及 ezmorph包共 5個,而Jackson除自身的以外只依賴于commons-logging
6务豺、Jackson提供完整基于節(jié)點的Tree Model磨总,以及完整的OJM數(shù)據(jù)綁定功能。
三笼沥、jackson的基本使用
1蚪燕、導入項目
compile 'com.squareup.retrofit2:converter-jackson:2.2.0'
如果這里有沖突報錯,這添加下面這段話
android {
...
}
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
}
}
2奔浅、DEMO
package com.ycxc.template.bean;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
/**
* Fuction: 網(wǎng)易新聞詳情<p>
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class NeteastNewsSummary {
@JsonProperty("postid")
public String postid;
@JsonProperty("hasCover")
public boolean hasCover;
@JsonProperty("hasHead")
public int hasHead;
@JsonProperty("replyCount")
public int replyCount;
@JsonProperty("hasImg")
public int hasImg;
@JsonProperty("digest")
public String digest;
@JsonProperty("hasIcon")
public boolean hasIcon;
@JsonProperty("docid")
public String docid;
@JsonProperty("title")
public String title;
@JsonProperty("order")
public int order;
@JsonProperty("priority")
public int priority;
@JsonProperty("lmodify")
public String lmodify;
@JsonProperty("boardid")
public String boardid;
@JsonProperty("photosetID")
public String photosetID;
@JsonProperty("template")
public String template;
@JsonProperty("votecount")
public int votecount;
@JsonProperty("skipID")
public String skipID;
@JsonProperty("alias")
public String alias;
@JsonProperty("skipType")
public String skipType;
@JsonProperty("cid")
public String cid;
@JsonProperty("hasAD")
public int hasAD;
@JsonProperty("imgsrc")
public String imgsrc;
@JsonProperty("tname")
public String tname;
@JsonProperty("ename")
public String ename;
@JsonProperty("ptime")
public String ptime;
/**
* title : 哈薩克斯坦中亞在建第1高樓爆炸起火
* tag : photoset
* imgsrc : http://img5.cache.netease.com/3g/2016/2/13/2016021318005710210.jpg
* subtitle :
* url : 00AN0001|110630
*/
@JsonProperty("ads")
public List<AdsEntity> ads;
/**
* imgsrc : http://img5.cache.netease.com/3g/2016/2/13/201602131446132dc50.jpg
*/
@JsonProperty("imgextra")
public List<ImgextraEntity> imgextra;
@JsonIgnoreProperties(ignoreUnknown = true)
public static class AdsEntity {
@JsonProperty("title")
public String title;
@JsonProperty("tag")
public String tag;
@JsonProperty("imgsrc")
public String imgsrc;
@JsonProperty("subtitle")
public String subtitle;
@JsonProperty("url")
public String url;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class ImgextraEntity {
@JsonProperty("imgsrc")
public String imgsrc;
}
}
四馆纳、相關屬性介紹
1 排除屬性
@JsonIgnore,一般標記在屬性或方法上的注解汹桦。序列化與反序列化時忽略被該注解修飾的成員鲁驶。
@JsonIgnoreProperties,如果是代理類舞骆,由于無法標記在屬性或方法上钥弯,所以径荔,可以標記在類聲明上;也作用于反序列化時的字段解析脆霎;
@JsonIgnoreProperties({"extra"})
類注解总处。在反序列化 json 數(shù)據(jù)時能夠忽略注解參數(shù)中對應的 json keys。
@JsonIgnoreProperties(ignoreUnknown = true)
//Jackson解析JSON數(shù)據(jù)時睛蛛,忽略未知的字段鹦马。(如果不設置,當JSON字段和bean字段不匹配時忆肾,會拋出異常)
2 屬性別名
@JsonProperty荸频,序列化/反序列化都有效;
3 屬性排序
@JsonPropertyOrder难菌,注釋在類聲明中试溯;
4 屬性格式轉換
使用自定義序列化/反序列化來處理;
@JsonSerialize郊酒,序列化遇绞;
@JsonDeserialize,反序列化燎窘;
注意:在使用hibernate的時候摹闽,查詢數(shù)據(jù)庫后產生的實體類是個代理類,這時候轉換JSON會報錯褐健;
解決方法有兩種:
1)設置FAIL_ON_EMPTY_BEANS屬性付鹿,告訴Jackson空對象不要拋異常;
mapper.disable(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS);
2)使用@JsonIgnoreProperties注解
在實體類聲明處加上@JsonIgnoreProperties(value = {"hibernateLazyInitializer", "handler"})注解蚜迅;
建議使用@JsonIgnoreProperties注解舵匾,這樣生成的JSON中不會產生多余的字段;
@JsonSerialize(using = JacksonUtil.JsonLocalDateSerializer.class)
屬性注解谁不。需要使用自定義序列化與反序列化解析器時坐梯,使用該注解修飾類成員變量。
5 父/子關聯(lián)
@JsonManagedReference刹帕,放在父親類中吵血;
@JsonBackReference,放在孩子類中偷溺;
6 去掉包裝
@JsonUnwrapped蹋辅,意思如下:
Ability to map JSON like
{
"name" : "home",
"latitude" : 127,
"longitude" : 345
}
to classes defined as:
class Place {
public String name;
@JsonUnwrapped
public Location location;
}
class Location {
public int latitude, longitude;
}
五、JacksonUtil
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
/**
* XML,JSON處理工具類
* 依靠jackson提供pojo2json/xml轉換
*
* @author HaiJia
*/
final public class JacksonUtil {
private static ObjectMapper objectMapper = new ObjectMapper();
private static ObjectMapper xmlMapper = new XmlMapper();
/**
* 防止反射調用構造器創(chuàng)建對象
*/
private JacksonUtil() {
throw new AssertionError();
}
/**
* 自定義日期序列化處理類
* LocalDateTime
* jdk8 support
*/
public static class JsonLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
@Override
public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
String localdateTimeStr = localDateTime.format(DateTimeFormatter.ISO_DATE_TIME);
jsonGenerator.writeString(localdateTimeStr);
}
}
/**
* 自定義日期序列化處理類
* LocalDateTime
* jdk8 support
*/
public static class JsonLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
String str = jsonParser.getText().trim();
return LocalDateTime.parse(str, DateTimeFormatter.ISO_DATE_TIME);
}
}
/**
* 自定義日期反序列化處理類
* LocalDate
* jdk8 support
*/
public static class JsonLocalDateDeserializer extends JsonDeserializer<LocalDate> {
@Override
public LocalDate deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String str = jsonParser.getText().trim();
return LocalDate.parse(str, DateTimeFormatter.ISO_DATE);
}
}
/**
* 自定義日期序列化類
* LocalDate
* jdk8 support
*/
public static class JsonLocalDateSerializer extends JsonSerializer<LocalDate> {
@Override
public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
String localdateStr = localDate.format(DateTimeFormatter.ISO_DATE);
jsonGenerator.writeString(localdateStr);
}
}
/**
* json數(shù)據(jù)轉pojo
*
* @param jsonStr json字符串
* @param cls 映射類型
* @param <T> 推導類型
* @return 推導類型json對象
*/
public static <T> T json2Pojo(String jsonStr, Class<T> cls) {
T object = null;
try {
object = objectMapper.readValue(jsonStr, cls);
} catch (IOException e) {
e.printStackTrace();
}
return object;
}
/**
* json數(shù)據(jù)轉PojoList
*
* @param jsonStr json數(shù)據(jù)
* @param cls 類型
* @param <T> 推導類型
* @return pojoList
*/
public static <T> List<T> jsonArray2PojoList(String jsonStr, Class<T> cls) {
List<T> pojoList = null;
try {
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
pojoList = objectMapper.readValue(jsonStr, listType);
} catch (IOException e) {
e.printStackTrace();
}
return pojoList;
}
/**
* pojo轉json
*
* @param obj pojo
* @return json字符串
*/
public static String pojo2Json(Object obj) {
String jsonStr = "";
try {
jsonStr = objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonStr;
}
/**
* json轉listMap
*
* @param jsonArray jsonArray字符串
* @return Listmap對象
*/
public static List<Map<String, Object>> jsonArray2ListMap(String jsonArray) {
List<Map<String, Object>> convertedListMap = null;
try {
convertedListMap = objectMapper.readValue(jsonArray, new TypeReference<List<Map<String, Object>>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
return convertedListMap;
}
/**
* json轉map
*
* @param json json字符串
* @return map對象
*/
public static Map<String, Object> json2Map(String json) {
Map<String, Object> convertedMap = null;
try {
convertedMap = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
return convertedMap;
}
/**
* listMap轉json
*
* @param listMap listMap
* @return
*/
public static String listMap2JsonArray(List<Map<String, Object>> listMap) {
String jsonStr = "";
try {
jsonStr = objectMapper.writeValueAsString(listMap);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return jsonStr;
}
/**
* xml轉pojo
*
* @param xmlStr xml字符串
* @param cls 映射對象
* @param <T> 推導類型
* @return pojo
*/
public static <T> T xml2Pojo(String xmlStr, Class<T> cls) {
T pojo = null;
try {
pojo = xmlMapper.readValue(xmlStr, cls);
} catch (IOException e) {
e.printStackTrace();
}
return pojo;
}
/**
* xml轉pojoList
*
* @param xmlStr xml字符串
* @param cls 映射對象
* @param <T> 推導類型
* @return pojo
*/
public static <T> List<T> xml2PojoList(String xmlStr, Class<T> cls) {
CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
List<T> pojoList = null;
try {
pojoList = xmlMapper.readValue(xmlStr, listType);
} catch (IOException e) {
e.printStackTrace();
}
return pojoList;
}
/**
* pojo轉xml
*
* @param object
*/
public static String pojo2Xml(Object object) {
String xml = "";
try {
xml = xmlMapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return xml;
}
/**
* xml轉map
*
* @param xmlStr xml字符串
* @return map對象
*/
public static Map<String, Object> xml2Map(String xmlStr) {
Map<String, Object> map = null;
try {
map = xmlMapper.readValue(xmlStr, new TypeReference<Map<String, Object>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
/**
* xml轉ListMap
*
* @param xmlStr xml字符串
* @return map對象
*/
public static List<Map<String, Object>> xml2ListMap(String xmlStr) {
List<Map<String, Object>> listMap = null;
try {
listMap = xmlMapper.readValue(xmlStr, new TypeReference<List<Map<String, Object>>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
return listMap;
}
}