jackson

今天在其他项目里面看到有人用jackson,就试着用了一下,并做点笔记。

一、jackson简介

解析原理:基于事件驱动,与GSON相同,先创建一个对应于JSON数据的JavaBean类就可以通过简单的操作解析出所需JSON数据。但和Gson解析不同的是,GSON可按需解析,即创建的JavaBean类不一定完全涵盖所要解析的JSON数据,按需创建属性,但Jackson解析对应的JavaBean必须把Json数据里面的所有key都有所对应,即必须把JSON内的数据所有解析出来,无法按需解析。但Jackson的解析速度和效率都要比GSON高

二、Jackson、JSON-lib、Gson的比较

网上偷来一张图作为对比Jackson、JSON-lib、Gson的解析速率

jackson_第1张图片
Paste_Image.png

测试总结:

1、显而易见,无论是哪种形式的转换,Jackson > Gson > Json-lib。
Jackson的处理能力甚至高出Json-lib有10倍左右
2、JSON-lib似乎已经停止更新,最新的版本也是基于JDK15,而Jackson的社区则较为活跃;
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提供完整基于节点的Tree Model,以及完整的OJM数据绑定功能。

三、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: 网易新闻详情

*/ @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 ads; /** * imgsrc : http://img5.cache.netease.com/3g/2016/2/13/201602131446132dc50.jpg */ @JsonProperty("imgextra") public List 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 数据时能够忽略注解参数中对应的 json keys。

@JsonIgnoreProperties(ignoreUnknown = true)
//Jackson解析JSON数据时,忽略未知的字段。(如果不设置,当JSON字段和bean字段不匹配时,会抛出异常)
2 属性别名

@JsonProperty,序列化/反序列化都有效;

3 属性排序

@JsonPropertyOrder,注释在类声明中;

4 属性格式转换

使用自定义序列化/反序列化来处理;
@JsonSerialize,序列化;
@JsonDeserialize,反序列化;

注意:在使用hibernate的时候,查询数据库后产生的实体类是个代理类,这时候转换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 父/子关联

@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();


    /**
     * 防止反射调用构造器创建对象
     */
    private JacksonUtil() {
        throw new AssertionError();
    }

    /**
     * 自定义日期序列化处理类
     * LocalDateTime
     * jdk8 support
     */
    public static class JsonLocalDateTimeSerializer extends JsonSerializer {


        @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 {


        @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 {

        @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 {


        @Override
        public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            String localdateStr = localDate.format(DateTimeFormatter.ISO_DATE);
            jsonGenerator.writeString(localdateStr);
        }
    }

    /**
     * json数据转pojo
     *
     * @param jsonStr json字符串
     * @param cls     映射类型
     * @param      推导类型
     * @return 推导类型json对象
     */
    public static  T json2Pojo(String jsonStr, Class cls) {
        T object = null;
        try {
            object = objectMapper.readValue(jsonStr, cls);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return object;
    }


    /**
     * json数据转PojoList
     *
     * @param jsonStr json数据
     * @param cls     类型
     * @param      推导类型
     * @return pojoList
     */
    public static  List jsonArray2PojoList(String jsonStr, Class cls) {
        List 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> jsonArray2ListMap(String jsonArray) {
        List> convertedListMap = null;
        try {
            convertedListMap = objectMapper.readValue(jsonArray, new TypeReference>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return convertedListMap;
    }

    /**
     * json转map
     *
     * @param json json字符串
     * @return map对象
     */
    public static Map json2Map(String json) {
        Map convertedMap = null;
        try {
            convertedMap = objectMapper.readValue(json, new TypeReference>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return convertedMap;
    }


    /**
     * listMap转json
     *
     * @param listMap listMap
     * @return
     */
    public static String listMap2JsonArray(List> listMap) {
        String jsonStr = "";
        try {
            jsonStr = objectMapper.writeValueAsString(listMap);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonStr;
    }


    /**
     * xml转pojo
     *
     * @param xmlStr xml字符串
     * @param cls    映射对象
     * @param     推导类型
     * @return pojo
     */
    public static  T xml2Pojo(String xmlStr, Class 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     推导类型
     * @return pojo
     */
    public static  List xml2PojoList(String xmlStr, Class cls) {
        CollectionType listType = objectMapper.getTypeFactory().constructCollectionType(List.class, cls);
        List 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 xml2Map(String xmlStr) {
        Map map = null;
        try {
            map = xmlMapper.readValue(xmlStr, new TypeReference>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * xml转ListMap
     *
     * @param xmlStr xml字符串
     * @return map对象
     */
    public static List> xml2ListMap(String xmlStr) {
        List> listMap = null;
        try {
            listMap = xmlMapper.readValue(xmlStr, new TypeReference>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        return listMap;
    }

}

你可能感兴趣的:(jackson)