成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Jackson的組成部分有哪些

這篇文章主要講解了“Jackson的組成部分有哪些”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Jackson的組成部分有哪些”吧!

成都創(chuàng)新互聯(lián),為您提供成都網(wǎng)站建設(shè)成都網(wǎng)站制作、網(wǎng)站營(yíng)銷推廣、網(wǎng)站開(kāi)發(fā)設(shè)計(jì),對(duì)服務(wù)混凝土攪拌機(jī)等多個(gè)行業(yè)擁有豐富的網(wǎng)站建設(shè)及推廣經(jīng)驗(yàn)。成都創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司成立于2013年,提供專業(yè)網(wǎng)站制作報(bào)價(jià)服務(wù),我們深知市場(chǎng)的競(jìng)爭(zhēng)激烈,認(rèn)真對(duì)待每位客戶,為客戶提供賞心悅目的作品。 與客戶共同發(fā)展進(jìn)步,是我們永遠(yuǎn)的責(zé)任!

什么是Jackson

Jackson是比較主流的基于Java的JSON類庫(kù),可用于Json和XML與JavaBean之間的序列化和反序列化。

沒(méi)看錯(cuò),Jackson也可以處理JavaBean與XML之間的轉(zhuǎn)換,基于jackson-dataformat-xml組件,而且比較JDK自帶XML實(shí)現(xiàn)更加高效和安全。而我們使用比較多的是處理JSON與JavaBean之間的功能。

Jackson主流到什么程度?單從Maven倉(cāng)庫(kù)中的統(tǒng)計(jì)來(lái)看,Jackson的使用量排位第一。而Spring Boot支持的三個(gè)JSON庫(kù)(Gson、Jackson、JSON-B)中,Jackson是首選默認(rèn)庫(kù)。

Jackson也有以下特點(diǎn):依賴少,簡(jiǎn)單易用,解析大Json速度快、內(nèi)存占用比較低、擁有靈活的API、方便擴(kuò)展與定制。

Jackson的組成部分

Jackson的核心模塊由三部分組成(從Jackson 2.x開(kāi)始):jackson-core、jackson-annotations、jackson-databind。

  • jackson-core:核心包,定義了低級(jí)流(Streaming)API,提供基于"流模式"解析。Jackson內(nèi)部實(shí)現(xiàn)正是通過(guò)高性能的流模式API的JsonGenerator和JsonParser來(lái)生成和解析json。

  • jackson-annotations,注解(Annotations)包,提供標(biāo)準(zhǔn)的Jackson注解功能;

  • jackson-databind:數(shù)據(jù)綁定(Databind)包,實(shí)現(xiàn)了數(shù)據(jù)綁定(和對(duì)象序列化)支持,它依賴于Streaming和Annotations包。提供基于“對(duì)象綁定”解析的API(ObjectMapper)和"樹(shù)模型"解析的API(JsonNode);基于"對(duì)象綁定"解析的API和"樹(shù)模型"解析的API依賴基于“流模式”解析的API。

下面看一下不同環(huán)境下相關(guān)組件的依賴引入情況。

在SpringBoot當(dāng)中,spring-boot-starter-web間接引入了Jackson組件,也就是如果你使用了SpringBoot框架,那么你的項(xiàng)目中已經(jīng)有了Jackson依賴。下面的依賴省略了version和scope項(xiàng)。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

web starter中依賴了json starter:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-json</artifactId>
</dependency>

json starter最終引入了Jackson:

<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jdk8</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.datatype</groupId>
  <artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
  <groupId>com.fasterxml.jackson.module</groupId>
  <artifactId>jackson-module-parameter-names</artifactId>
</dependency>

上面已經(jīng)提到過(guò),jackson-databind依賴于Streaming和Annotations包,因此,引入jackson-databind相當(dāng)于引入了jackson-core和jackson-annotations。

通常情況下,我們單獨(dú)使用時(shí),根據(jù)需要通過(guò)Maven引入jackson-databind、jackson-core和jackson-annotations即可。

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

對(duì)于SpringBoot項(xiàng)目,基本上不用再額外添加依賴。

Jackson核心類ObjectMapper

Jackson提供了三種JSON的處理方式,分別是:數(shù)據(jù)綁定、JSON樹(shù)模型、流式API。其中前兩項(xiàng)功能都是基于ObjectMapper來(lái)實(shí)現(xiàn)的,而流式API功能則需要基于更底層的JsonGenerator和JsonParser來(lái)實(shí)現(xiàn)。

通常情況下我們使用ObjectMapper類就足夠了,它擁有以下功能:

  • 從字符串、流或文件中解析JSON,并創(chuàng)建表示已解析的JSON的Java對(duì)象(反序列化)。

  • 將Java對(duì)象構(gòu)建成JSON字符串(序列化)。

  • 將JSON解析為自定義類的對(duì)象,也可以解析JSON樹(shù)模型的對(duì)象;

ObjectMapper基于JsonParser和JsonGenerator來(lái)實(shí)現(xiàn)JSON實(shí)際的讀/寫。這一點(diǎn)看一下ObjectMapper的構(gòu)造方法即可明白。

具體實(shí)例

Jackson的常見(jiàn)使用,就不逐一講解了,通過(guò)一些列的實(shí)例給大家展示一下,每個(gè)實(shí)例當(dāng)中都會(huì)通過(guò)注釋進(jìn)行說(shuō)明。

常見(jiàn)簡(jiǎn)單使用

下面的示例是我們經(jīng)常會(huì)用到的用法演示,主要涉及到JavaBean和Json字符串之間的轉(zhuǎn)換。

Jackson在將json轉(zhuǎn)換為JavaBean屬性時(shí),默認(rèn)是通過(guò)Json字段的名稱與Java對(duì)象中的getter和setter方法進(jìn)行匹配進(jìn)行綁定。

Jackson取getter和setter方法名稱中去除“get”和“set”部分,并將首字母小寫。例如Json中的name,與JavaBean中的getName()和setName()進(jìn)行匹配。

但并不是所有的屬性都可以被序列化和反序列化,基本上遵循一下規(guī)則:

  • public修飾的屬性可序列化和反序列化。

  • 屬性提供public的getter/setter方法,該屬性可序列化和反序列化。

  • 屬性只有public的setter方法,而無(wú)public的getter方法,該屬性只能用于反序列化。

@Slf4j
public class JacksonTest {

    /**
     * JavaBean轉(zhuǎn)JSON字符串
     */
    @Test
    public void testJavaBeanToJson() {
        WeChat weChat = new WeChat();
        weChat.setId("zhuan2quan");
        weChat.setName("程序新視界");
        weChat.setInterest(new String[]{"Java", "Spring Boot", "JVM"});

        ObjectMapper mapper = new ObjectMapper();
        try {
            String result = mapper.writeValueAsString(weChat);
            System.out.println(result);
        } catch (JsonProcessingException e) {
            log.error("轉(zhuǎn)換異常", e);
        }
    }

    /**
     * JSON字符串轉(zhuǎn)JavaBean
     */
    @Test
    public void testJsonToJavaBean() {
        String json = "{\"id\":\"zhuan2quan\",\"name\":\"程序新視界\",\"interest\":[\"Java\",\"Spring Boot\",\"JVM\"]}";
        ObjectMapper mapper = new ObjectMapper();
        try {
            WeChat weChat = mapper.readValue(json, WeChat.class);
            System.out.println(weChat);
        } catch (JsonProcessingException e) {
            log.error("解析異常", e);
        }
    }

    /**
     * JSON字符串轉(zhuǎn)Map集合
     */
    @Test
    public void testJsonToMap() {
        String json = "{\"id\":\"zhuan2quan\",\"name\":\"程序新視界\",\"interest\":[\"Java\",\"Spring Boot\",\"JVM\"]}";
        ObjectMapper mapper = new ObjectMapper();
        try {
            // 對(duì)泛型的反序列化,使用TypeReference可以明確的指定反序列化的類型。
            Map<String, Object> map = mapper.readValue(json, new TypeReference<Map<String, Object>>() {
            });
            System.out.println(map);
        } catch (JsonProcessingException e) {
            log.error("解析異常", e);
        }
    }

    /**
     * JavaBean轉(zhuǎn)文件
     */
    @Test
    public void testJavaBeanToFile() {
        WeChat weChat = new WeChat();
        weChat.setId("zhuan2quan");
        weChat.setName("程序新視界");
        weChat.setInterest(new String[]{"Java", "Spring Boot", "JVM"});

        ObjectMapper mapper = new ObjectMapper();
        try {
            //寫到文件
            mapper.writeValue(new File("/json.txt"), weChat);

            //從文件中讀取
            WeChat weChat1 = mapper.readValue(new File("/json.txt"), WeChat.class);
            System.out.println(weChat1);
        } catch (IOException e) {
            log.error("轉(zhuǎn)換異常", e);
        }
    }

    /**
     * JavaBean轉(zhuǎn)字節(jié)流
     */
    @Test
    public void testJavaBeanToBytes() {
        WeChat weChat = new WeChat();
        weChat.setId("zhuan2quan");
        weChat.setName("程序新視界");
        weChat.setInterest(new String[]{"Java", "Spring Boot", "JVM"});

        ObjectMapper mapper = new ObjectMapper();
        try {
            // 寫為字節(jié)流
            byte[] bytes = mapper.writeValueAsBytes(weChat);
            // 從字節(jié)流讀取
            WeChat weChat1 = mapper.readValue(bytes, WeChat.class);
            System.out.println(weChat1);
        } catch (IOException e) {
            log.error("轉(zhuǎn)換異常", e);
        }
    }
}

上述代碼用到了lombok注解和單元測(cè)試注解,根據(jù)需要可進(jìn)行替換。

JSON樹(shù)模型

如果Json字符串比較大,則可使用JSON樹(shù)模型來(lái)靈活的獲取所需的字段內(nèi)容。在Jackson中提供了get、path、has等方法來(lái)獲取或判斷。

下面直接看兩個(gè)示例:

@Slf4j
public class JacksonNodeTest {

    /**
     * JavaBean轉(zhuǎn)JSON字符串
     */
    @Test
    public void testJsonNode() {
        // 構(gòu)建JSON樹(shù)
        ObjectMapper mapper = new ObjectMapper();
        ObjectNode root = mapper.createObjectNode();
        root.put("id", "zhuan2quan");
        root.put("name", "程序新視界");
        ArrayNode interest = root.putArray("interest");
        interest.add("Java");
        interest.add("Spring Boot");
        interest.add("JVM");

        // JSON樹(shù)轉(zhuǎn)JSON字符串
        String json = null;
        try {
            json = mapper.writeValueAsString(root);
        } catch (JsonProcessingException e) {
            log.error("Json Node轉(zhuǎn)換異常", e);
        }
        System.out.println(json);
    }

    /**
     * 解析JSON字符串為JSON樹(shù)模型
     */
    @Test
    public void testJsonToJsonNode() {
        String json = "{\"id\":\"zhuan2quan\",\"name\":\"程序新視界\",\"interest\":[\"Java\",\"Spring Boot\",\"JVM\"]}";
        ObjectMapper mapper = new ObjectMapper();
        try {
            // 將JSON字符串轉(zhuǎn)為JSON樹(shù)
            JsonNode jsonNode = mapper.readTree(json);
            String name = jsonNode.path("name").asText();
            System.out.println(name);

            JsonNode interestNode = jsonNode.get("interest");
            if (interestNode.isArray()){
                for (JsonNode node : interestNode){
                    System.out.println(node.asText());
                }
            }
        } catch (JsonProcessingException e) {
            log.error("Json Node轉(zhuǎn)換異常", e);
        }
    }
}

其中g(shù)et方法和path功能相似,區(qū)別在于如果要讀取的key在Json串中不存在時(shí),get方法會(huì)null,而path會(huì)返回MissingNode實(shí)例對(duì)象,在鏈路方法情況下保證不會(huì)拋出異常。

流式API

除了上述兩種形式,還可以基于底層的流式API來(lái)進(jìn)行操作,主要通過(guò)JsonGenerator和JsonParser兩個(gè)API,但操作起來(lái)比較復(fù)雜,就不再這里演示了。

格式化統(tǒng)一配置

在使用ObjectMapper時(shí),會(huì)存在一些字段在某些情況下不需要進(jìn)行序列化或反序列化,同時(shí)還可能需要指定格式化的一些信息等。此時(shí),可以通過(guò)ObjectMapper進(jìn)行配置。

//反序列化時(shí)忽略json中存在但Java對(duì)象不存在的屬性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
//序列化時(shí)日期格式默認(rèn)為yyyy-MM-dd'T'HH:mm:ss.SSSZ
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
//序列化時(shí)自定義時(shí)間日期格式
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
//序列化時(shí)忽略值為null的屬性
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//序列化時(shí)忽略值為默認(rèn)值的屬性
mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT);

針對(duì)于配置項(xiàng),在2.2版本中新增了一個(gè)ObjectMapper的實(shí)現(xiàn)類JsonMapper,功能與ObjectMapper一致。不過(guò)新增了一個(gè)builder方法??梢灾苯油ㄟ^(guò)JsonMapper.builder().configure()方法來(lái)進(jìn)行配置,最后獲得一個(gè)JsonMapper對(duì)象。JsonMapper的其他方法基本都集成自O(shè)bjectMapper。

注解的使用

上面通過(guò)統(tǒng)一配置可對(duì)全局格式的序列化和反序列化進(jìn)行配置,但某些個(gè)別的場(chǎng)景下,需要針對(duì)具體的字段進(jìn)行配置,這就需要用注解。比如當(dāng)Json字符串中的字段與Java對(duì)象中的屬性不一致時(shí),就需要通過(guò)注解來(lái)建立它們直接的關(guān)系。

@JsonProperty,作用JavaBean字段上,指定一個(gè)字段用于JSON映射,默認(rèn)情況下映射的JSON字段與注解的字段名稱相同??赏ㄟ^(guò)value屬性指定映射的JSON的字段名稱。

@JsonIgnore可用于字段、getter/setter、構(gòu)造函數(shù)參數(shù)上,指定字段不參與序列化和反序列化。

@JsonIgnoreProperties作用于類上,序列化時(shí)@JsonIgnoreProperties({“prop1”, “prop2”})會(huì)忽略pro1和pro2兩個(gè)屬性。反序列化時(shí)@JsonIgnoreProperties(ignoreUnknown=true)會(huì)忽略類中不存在的字段。

@JsonFormat作用于字段上,通常用來(lái)進(jìn)行格式化操作。

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date date;

如果JavaBean中的時(shí)間字段使用的是JDK8新增的時(shí)間日期(LocalDate/LocalTime/LocalDateTime)類型的話,需要添加jackson-datatype-jsr310依賴。在講依賴部分時(shí),SpringBoot默認(rèn)引入的依賴中就有這個(gè)。

當(dāng)然,還有一些其他的注解,比如@JsonPropertyOrder、@JsonRootName、@JsonAnySetter、@JsonAnyGetter、@JsonNaming等,當(dāng)使用時(shí)參考對(duì)應(yīng)的文檔和示例看一下就可以,這里就不再一一列出了。

自定義解析器

如果上面的注解和統(tǒng)一配置還無(wú)法滿足需求,可自定義解析器,示例如下:

public class MyFastjsonDeserialize extends JsonDeserializer<Point> {

    @Override
    public Point deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        JsonNode node = jsonParser.getCodec().readTree(jsonParser);
        Iterator<JsonNode> iterator = node.get("coordinates").elements();
        List<Double> list = new ArrayList<>();
        while (iterator.hasNext()) {
            list.add(iterator.next().asDouble());
        }
        return new Point(list.get(0), list.get(1));
    }
}

定義完成之后,注冊(cè)到Mapper中:

ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Point.class, new MyFastjsonDeserialize());
objectMapper.registerModule(module);

Jackson處理XML

Jackson也可以通過(guò)jackson-dataformat-xml包提供了處理XML的功能。在處理XML時(shí)建議使用woodstox-core包,它是一個(gè)XML的實(shí)現(xiàn),比JDK自帶XML實(shí)現(xiàn)更加高效,也更加安全。

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

如果使用Java 9及以上版本,可能會(huì)出現(xiàn)java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException異常,這是因?yàn)镴ava 9實(shí)現(xiàn)了JDK的模塊化,將原本和JDK打包在一起的JAXB實(shí)現(xiàn)分隔出來(lái)。所以需要手動(dòng)添加JAXB的實(shí)現(xiàn)。

<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>

下面是代碼示例,基本上和JSON的API非常相似,XmlMapper實(shí)際上就是ObjectMapper的子類。

@Test
public void testXml(){
    WeChat weChat = new WeChat();
    weChat.setId("zhuan2quan");
    weChat.setName("程序新視界");
    weChat.setInterest(new String[]{"Java", "Spring Boot", "JVM"});

    XmlMapper xmlMapper = new XmlMapper();
    try {
        String xml = xmlMapper.writeValueAsString(weChat);
        System.out.println(xml);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
}

執(zhí)行之后,輸出結(jié)果:

<WeChat>
    <id>zhuan2quan</id>
    <name>程序新視界</name>
    <interest>
        <interest>Java</interest>
        <interest>Spring Boot</interest>
        <interest>JVM</interest>
    </interest>
</WeChat>

Spring Boot中的集成

在最開(kāi)始的時(shí)候,我們已經(jīng)看到Spring Boot默認(rèn)引入了Jackson的依賴,而且也用我們做什么額外的操作,其實(shí)已經(jīng)在使用Jackson進(jìn)行Json格式的數(shù)據(jù)與MVC中參數(shù)進(jìn)行綁定操作了。

如果Spring Boot默認(rèn)的配置并不適合項(xiàng)目需求,也可以通過(guò)內(nèi)置的配置進(jìn)行配置,以application.yml配置為例,可通過(guò)指定以下屬性進(jìn)行相應(yīng)選項(xiàng)的配置:

#指定日期格式,比如yyyy-MM-dd HH:mm:ss,或者具體的格式化類的全限定名
spring.jackson.date-format 
#是否開(kāi)啟Jackson的反序列化
spring.jackson.deserialization
#是否開(kāi)啟json的generators.
spring.jackson.generator
#指定Joda date/time的格式,比如yyyy-MM-ddHH:mm:ss). 如果沒(méi)有配置的話,dateformat會(huì)作為backup
spring.jackson.joda-date-time-format
#指定json使用的Locale.
spring.jackson.locale
#是否開(kāi)啟Jackson通用的特性.
spring.jackson.mapper
#是否開(kāi)啟jackson的parser特性.
spring.jackson.parser
#指定PropertyNamingStrategy(CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES)或者指定PropertyNamingStrategy子類的全限定類名.
spring.jackson.property-naming-strategy
#是否開(kāi)啟jackson的序列化.
spring.jackson.serialization
#指定序列化時(shí)屬性的inclusion方式,具體查看JsonInclude.Include枚舉.
spring.jackson.serialization-inclusion
#指定日期格式化時(shí)區(qū),比如America/Los_Angeles或者GMT+10.
spring.jackson.time-zone

Spring Boot自動(dòng)配置非常方便,但某些時(shí)候需要我們手動(dòng)配置Bean來(lái)替代自動(dòng)配置的Bean。可通過(guò)如下形式進(jìn)行配置:

@Configuration
public class JacksonConfig {
    @Bean
    @Qualifier("json")
    public ObjectMapper jsonMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper mapper = builder.createXmlMapper(false)
                .build();
        mapper.enable(SerializationFeature.INDENT_OUTPUT);
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        return mapper;
    }
}

配置完成,可在使用的地方直接注入即可:

@Resource
private ObjectMapper jsonMapper;

對(duì)于上面的注入,可能會(huì)有朋友問(wèn)了,是否有線程安全的問(wèn)題?這個(gè)不用擔(dān)心ObjectMapper是線程安全的。

感謝各位的閱讀,以上就是“Jackson的組成部分有哪些”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Jackson的組成部分有哪些這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

網(wǎng)站名稱:Jackson的組成部分有哪些
轉(zhuǎn)載來(lái)源:http://jinyejixie.com/article18/ggijgp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、網(wǎng)站建設(shè)、品牌網(wǎng)站建設(shè)做網(wǎng)站、企業(yè)建站、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作
桂林市| 长垣县| 沙雅县| 砀山县| 黄骅市| 新巴尔虎右旗| 平顺县| 卢龙县| 嘉峪关市| 台江县| 高密市| 北辰区| 屯昌县| 宁城县| 广水市| 建水县| 固阳县| 汤原县| 沈丘县| 五华县| 东乡族自治县| 关岭| 抚顺县| 建瓯市| 翁源县| 丰都县| 随州市| 罗田县| 常德市| 台山市| 石狮市| 西青区| 林芝县| 新安县| 闵行区| 吴江市| 平山县| 张家川| 高要市| 聊城市| 太白县|