欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中Jackson快速入門

 更新時間:2021年01月11日 11:19:52   作者:過了即是客  
這篇文章主要介紹了Java中Jackson快速入門,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

Java生態(tài)圈中有很多處理JSON和XML格式化的類庫,Jackson是其中比較著名的一個。雖然JDK自帶了XML處理類庫,但是相對來說比較低級,使用本文介紹的Jackson等高級類庫處理起來會方便很多。

引入類庫

由于Jackson相關類庫按照功能分為幾個相對獨立的,所以需要同時引入多個類庫,為了方便我將版本號單獨提取出來設置,相關Gradle配置如下。

ext {
  jacksonVersion = '2.9.5'
}

dependencies {
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: jacksonVersion
  // 引入XML功能
  compile group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: jacksonVersion
  // 比JDK自帶XML實現更高效的類庫
  compile group: 'com.fasterxml.woodstox', name: 'woodstox-core', version: '5.1.0'
  // Java 8 新功能
  compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-parameter-names', version: jacksonVersion
  compile group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jdk8', version: jacksonVersion

  compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.16.22'
}

Maven配置請去mvnrepository搜索。

Jackson注解

Jackson類庫包含了很多注解,可以讓我們快速建立Java類與JSON之間的關系。詳細文檔可以參考Jackson-Annotations。下面介紹一下常用的。

屬性命名

@JsonProperty注解指定一個屬性用于JSON映射,默認情況下映射的JSON屬性與注解的屬性名稱相同,不過可以使用該注解的value值修改JSON屬性名,該注解還有一個index屬性指定生成JSON屬性的順序,如果有必要的話。

屬性包含

還有一些注解可以管理在映射JSON的時候包含或排除某些屬性,下面介紹一下常用的幾個。

@JsonIgnore注解用于排除某個屬性,這樣該屬性就不會被Jackson序列化和反序列化。

@JsonIgnoreProperties注解是類注解。在序列化為JSON的時候,@JsonIgnoreProperties({"prop1", "prop2"})會忽略pro1和pro2兩個屬性。在從JSON反序列化為Java類的時候,@JsonIgnoreProperties(ignoreUnknown=true)會忽略所有沒有Getter和Setter的屬性。該注解在Java類和JSON不完全匹配的時候很有用。

@JsonIgnoreType也是類注解,會排除所有指定類型的屬性。

序列化相關

@JsonPropertyOrder和@JsonProperty的index屬性類似,指定屬性序列化時的順序。

@JsonRootName注解用于指定JSON根屬性的名稱。

處理JSON

簡單映射

我們用Lombok設置一個簡單的Java類。

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Friend {
  private String nickname;
  private int age;
}

然后就可以處理JSON數據了。首先需要一個ObjectMapper對象,序列化和反序列化都需要它。

    ObjectMapper mapper = new ObjectMapper();
    Friend friend = new Friend("yitian", 25);

    // 寫為字符串
    String text = mapper.writeValueAsString(friend);
    // 寫為文件
    mapper.writeValue(new File("friend.json"), friend);
    // 寫為字節(jié)流
    byte[] bytes = mapper.writeValueAsBytes(friend);
    System.out.println(text);
    // 從字符串中讀取
    Friend newFriend = mapper.readValue(text, Friend.class);
    // 從字節(jié)流中讀取
    newFriend = mapper.readValue(bytes, Friend.class);
    // 從文件中讀取
    newFriend = mapper.readValue(new File("friend.json"), Friend.class);
    System.out.println(newFriend);

程序結果如下。可以看到生成的JSON屬性和Java類中定義的一致。

{"nickname":"yitian","age":25}
Friend(nickname=yitian, age=25)

集合的映射

除了使用Java類進行映射之外,我們還可以直接使用Map和List等Java集合組織JSON數據,在需要的時候可以使用readTree方法直接讀取JSON中的某個屬性值。需要注意的是從JSON轉換為Map對象的時候,由于Java的類型擦除,所以類型需要我們手動用new TypeReference<T>給出。

    ObjectMapper mapper = new ObjectMapper();

    Map<String, Object> map = new HashMap<>();
    map.put("age", 25);
    map.put("name", "yitian");
    map.put("interests", new String[]{"pc games", "music"});

    String text = mapper.writeValueAsString(map);
    System.out.println(text);

    Map<String, Object> map2 = mapper.readValue(text, new TypeReference<Map<String, Object>>() {
    });
    System.out.println(map2);

    JsonNode root = mapper.readTree(text);
    String name = root.get("name").asText();
    int age = root.get("age").asInt();

    System.out.println("name:" + name + " age:" + age);

程序結果如下。

{"name":"yitian","interests":["pc games","music"],"age":25}
{name=yitian, interests=[pc games, music], age=25}
name:yitian age:25

Jackson配置

Jackson預定義了一些配置,我們通過啟用和禁用某些屬性可以修改Jackson運行的某些行為。詳細文檔參考JacksonFeatures。下面我簡單翻譯一下Jackson README上列出的一些屬性。

// 美化輸出
mapper.enable(SerializationFeature.INDENT_OUTPUT);
// 允許序列化空的POJO類
// (否則會拋出異常)
mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
// 把java.util.Date, Calendar輸出為數字(時間戳)
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

// 在遇到未知屬性的時候不拋出異常
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 強制JSON 空字符串("")轉換為null對象值:
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

// 在JSON中允許C/C++ 樣式的注釋(非標準,默認禁用)
mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
// 允許沒有引號的字段名(非標準)
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// 允許單引號(非標準)
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// 強制轉義非ASCII字符
mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
// 將內容包裹為一個JSON屬性,屬性名由@JsonRootName注解指定
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);

這里有三個方法,configure方法接受配置名和要設置的值,Jackson 2.5版本新加的enable和disable方法則直接啟用和禁用相應屬性,我推薦使用后面兩個方法。

用注解管理映射

前面介紹了一些Jackson注解,下面來應用一下這些注解。首先來看看使用了注解的Java類。

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonRootName("FriendDetail")
@JsonIgnoreProperties({"uselessProp1", "uselessProp3"})
public class FriendDetail {
  @JsonProperty("NickName")
  private String name;
  @JsonProperty("Age")
  private int age;
  private String uselessProp1;
  @JsonIgnore
  private int uselessProp2;
  private String uselessProp3;
}

然后看看代碼。需要注意的是,由于設置了排除的屬性,所以生成的JSON和Java類并不是完全對應關系,所以禁用DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES是必要的。

    ObjectMapper mapper = new ObjectMapper();
    //mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    FriendDetail fd = new FriendDetail("yitian", 25, "", 0, "");
    String text = mapper.writeValueAsString(fd);
    System.out.println(text);

    FriendDetail fd2 = mapper.readValue(text, FriendDetail.class);
    System.out.println(fd2);

運行結果如下。可以看到生成JSON的時候忽略了我們制定的值,而且在轉換為Java類的時候對應的屬性為空。

{"NickName":"yitian","Age":25}
FriendDetail(name=yitian, age=25, uselessProp1=null, uselessProp2=0, uselessProp3=null)

然后取消注釋代碼中的那行,也就是啟用WRAP_ROOT_VALUE功能,再運行一下程序,運行結果如下??梢钥吹缴傻腏SON結果發(fā)生了變化,而且由于JSON結果變化,所以Java類轉換失敗(所有字段值全為空)。WRAP_ROOT_VALUE這個功能在有些時候比較有用,因為有些JSON文件需要這種結構。

{"FriendDetail":{"NickName":"yitian","Age":25}}
FriendDetail(name=null, age=0, uselessProp1=null, uselessProp2=0, uselessProp3=null)

Java8日期時間類支持

Java8增加了一套全新的日期時間類,Jackson對此也有支持。這些支持是以Jackson模塊形式提供的,所以首先就是注冊這些模塊。

    ObjectMapper mapper = new ObjectMapper()
        .registerModule(new JavaTimeModule())
        .registerModule(new ParameterNamesModule())
        .registerModule(new Jdk8Module());

導入類庫之后,Jackson也可以自動搜索所有模塊,不需要我們手動注冊。

mapper.findAndRegisterModules();

我們新建一個帶有LocalDate字段的Java類。

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonRootName("Person")
public class Person {
  @JsonProperty("Name")
  private String name;
  @JsonProperty("NickName")
  private String nickname;
  @JsonProperty("Age")
  private int age;
  @JsonProperty("IdentityCode")
  private String identityCode;
  @JsonProperty
  @JsonFormat(pattern = "yyyy-MM-DD")
  private LocalDate birthday;

}

然后來看看代碼。

  static void java8DateTime() throws IOException {
    Person p1 = new Person("yitian", "易天", 25, "10000", LocalDate.of(1994, 1, 1));
    ObjectMapper mapper = new ObjectMapper()
        .registerModule(new JavaTimeModule());
    //mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    String text = mapper.writeValueAsString(p1);
    System.out.println(text);

    Person p2 = mapper.readValue(text, Person.class);
    System.out.println(p2);
  }

運行結果如下??梢钥吹?,生成的JSON日期變成了[1994,1,1]這樣的時間戳形式,一般情況下不符合我們的要求。

{"birthday":[1994,1,1],"Name":"yitian","NickName":"易天","Age":25,"IdentityCode":"10000"}
Person(name=yitian, nickname=易天, age=25, identityCode=10000, birthday=1994-01-01)

取消注釋那行代碼,程序運行結果如下。這樣一來就變成了我們一般使用的形式了。如果有格式需要的話,可以使用@JsonFormat(pattern = "yyyy-MM-DD")注解格式化日期顯示。

{"birthday":"1994-01-01","Name":"yitian","NickName":"易天","Age":25,"IdentityCode":"10000"}
Person(name=yitian, nickname=易天, age=25, identityCode=10000, birthday=1994-01-01)

處理XML

Jackson是一個處理JSON的類庫,不過它也通過jackson-dataformat-xml包提供了處理XML的功能。Jackson建議我們在處理XML的時候使用woodstox-core包,它是一個XML的實現,比JDK自帶XML實現更加高效,也更加安全。

這里有個注意事項,如果你正在使用Java 9以上的JDK,可能會出現java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException異常,這是因為Java 9實現了JDK的模塊化,將原本和JDK打包在一起的JAXB實現分隔出來。所以這時候需要我們手動添加JAXB的實現。在Gradle中添加下面的代碼即可。

compile group: 'javax.xml.bind', name: 'jaxb-api', version: '2.3.0'

注解

Jackson XML除了使用Jackson JSON和JDK JAXB的一些注解之外,自己也定義了一些注解。下面簡單介紹一下幾個常用注解。

@JacksonXmlProperty注解有三個屬性,namespace和localname屬性用于指定XML命名空間的名稱,isAttribute指定該屬性作為XML的屬性()還是作為子標簽().

@JacksonXmlRootElement注解有兩個屬性,namespace和localname屬性用于指定XML根元素命名空間的名稱。

@JacksonXmlText注解將屬性直接作為未被標簽包裹的普通文本表現。

@JacksonXmlCData將屬性包裹在CDATA標簽中。

XML映射

新建如下一個Java類。

@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonRootName("Person")
public class Person {
  @JsonProperty("Name")
  private String name;
  @JsonProperty("NickName")
  //@JacksonXmlText
  private String nickname;
  @JsonProperty("Age")
  private int age;
  @JsonProperty("IdentityCode")
  @JacksonXmlCData
  private String identityCode;
  @JsonProperty("Birthday")
  //@JacksonXmlProperty(isAttribute = true)
  @JsonFormat(pattern = "yyyy/MM/DD")
  private LocalDate birthday;

}

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

    Person p1 = new Person("yitian", "易天", 25, "10000", LocalDate.of(1994, 1, 1));
    XmlMapper mapper = new XmlMapper();
    mapper.findAndRegisterModules();
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    String text = mapper.writeValueAsString(p1);
    System.out.println(text);

    Person p2 = mapper.readValue(text, Person.class);
    System.out.println(p2);

運行結果如下。

<Person>
 <Name>yitian</Name>
 <NickName>易天</NickName>
 <Age>25</Age>
 <IdentityCode><![CDATA[10000]]></IdentityCode>
 <Birthday>1994/01/01</Birthday>
</Person>

Person(name=yitian, nickname=易天, age=25, identityCode=10000, birthday=1994-01-01)

如果取消那兩行注釋,那么運行結果如下??梢钥吹絁ackson XML注解對生成的XML的控制效果。

<Person birthday="1994/01/01">
 <Name>yitian</Name>易天
 <Age>25</Age>
 <IdentityCode><![CDATA[10000]]></IdentityCode>
</Person>

Person(name=yitian, nickname=null, age=25, identityCode=10000, birthday=1994-01-01)

Spring Boot集成

自動配置

Spring Boot對Jackson的支持非常完善,只要我們引入相應類庫,Spring Boot就可以自動配置開箱即用的Bean。Spring自動配置的ObjectMapper(或者XmlMapper)作了如下配置,基本上可以適應大部分情況。

  • 禁用了MapperFeature.DEFAULT_VIEW_INCLUSION
  • 禁用了DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
  • 禁用了SerializationFeature.WRITE_DATES_AS_TIMESTAMPS

如果需要修改自動配置的ObjectMapper屬性也非常簡單,Spring Boot提供了一組環(huán)境變量,直接在application.properties文件中修改即可。

|Jackson枚舉|Spring環(huán)境變量|
|—–|—–|
com.fasterxml.jackson.databind.DeserializationFeature|spring.jackson.deserialization.=true|false
com.fasterxml.jackson.core.JsonGenerator.Feature|spring.jackson.generator.=true|false
com.fasterxml.jackson.databind.MapperFeature|spring.jackson.mapper.=true|false
com.fasterxml.jackson.core.JsonParser.Feature|spring.jackson.parser.=true|false
com.fasterxml.jackson.databind.SerializationFeature|spring.jackson.serialization.=true|false
com.fasterxml.jackson.annotation.JsonInclude.Include|spring.jackson.default-property-inclusion=always|non_null|non_absent|non_default|non_empty

由于Spring會同時配置相應的HttpMessageConverters,所以我們其實要做的很簡單,用Jackson注解標注好要映射的Java類,然后直接讓控制器返回對象即可!下面是一個Java類。

@JsonRootName("person")
public class Person {
  @JsonProperty
  private String name;
  @JsonProperty
  private int id;
  @JsonFormat(pattern = "yyyy-MM-DD")
  private LocalDate birthday;

  public Person(String name, int id, LocalDate birthday) {
    this.name = name;
    this.id = id;
    this.birthday = birthday;
  }
}

然后是控制器代碼。在整個過程中我們只需要引入Jackson類庫,然后編寫業(yè)務代碼就好了。關于如何配置Jackson類庫,我們完全不需要管,這就是Spring Boot的方便之處。

@Controller
public class MainController {
  private Person person = new Person("yitian", 10000, LocalDate.of(1994, 1, 1));

  @RequestMapping("/")
  public String index() {
    return "index";
  }


  @RequestMapping(value = "/json", produces = "application/json")
  @ResponseBody
  public Person json() {
    return person;
  }
}

進入localhost:8080/xml就可以看到對應結果了。

手動配置

Spring Boot自動配置非常方便,但不是萬能的。在必要的時候,我們需要手動配置Bean來替代自動配置的Bean。

@Configuration
public class JacksonConfig {
  @Bean
  @Primary
  @Qualifier("xml")
  public XmlMapper xmlMapper(Jackson2ObjectMapperBuilder builder) {
    XmlMapper mapper = builder.createXmlMapper(true)
        .build();
    mapper.enable(SerializationFeature.INDENT_OUTPUT);
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
    return mapper;
  }

  @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;
  }
}

然后在需要的地方進行依賴注入。需要注意為了區(qū)分ObjectMapper和XmlMapper,需要使用@Qualifier注解進行標記。

@Controller
public class MainController {
  private ObjectMapper jsonMapper;
  private XmlMapper xmlMapper;
  private Person person = new Person("yitian", 10000, LocalDate.of(1994, 1, 1));

  public MainController(@Autowired @Qualifier("json") ObjectMapper jsonMapper, @Autowired @Qualifier("xml") XmlMapper xmlMapper) {
    this.jsonMapper = jsonMapper;
    this.xmlMapper = xmlMapper;
  }

以上就是Jackson類庫的一些介紹,希望對大家有所幫助。項目代碼在我的Github,感興趣的同學可以看看。

到此這篇關于Java中Jackson快速入門的文章就介紹到這了,更多相關Jackson快速入門內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Mybatis之如何攔截慢SQL日志記錄

    Mybatis之如何攔截慢SQL日志記錄

    這篇文章主要介紹了Mybatis之如何攔截慢SQL日志記錄問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • 再也不用怕! 讓你徹底搞明白Java內存分布

    再也不用怕! 讓你徹底搞明白Java內存分布

    做Java的大都沒有c++ 的那種分配內存的煩惱,因為Java 幫我們管理內存,但是這并不代表我們不需要了解Java的內存結構,因為線上經常出現內存的問題,今天聊一下內存的問題,需要的朋友可以參考下
    2021-06-06
  • spring boot里增加表單驗證hibernate-validator并在freemarker模板里顯示錯誤信息(推薦)

    spring boot里增加表單驗證hibernate-validator并在freemarker模板里顯示錯誤信息(推

    這篇文章主要介紹了spring boot里增加表單驗證hibernate-validator并在freemarker模板里顯示錯誤信息的相關資料,需要的朋友可以參考下
    2018-01-01
  • Spring?Boot自定義?Starter并推送到遠端公服的詳細代碼

    Spring?Boot自定義?Starter并推送到遠端公服的詳細代碼

    這篇文章主要介紹了Spring?Boot自定義?Starter并推送到遠端公服,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-09-09
  • java實現統(tǒng)一異常處理的示例

    java實現統(tǒng)一異常處理的示例

    一個全局異常處理類需要處理三類異常1.業(yè)務類異常,2.運行時異常 ,3.Error,本文給大家介紹java實現統(tǒng)一異常處理的示例,感興趣的朋友一起看看吧
    2021-06-06
  • Java 自定義Spring框架以及Spring框架的基本使用

    Java 自定義Spring框架以及Spring框架的基本使用

    Spring框架是由于軟件開發(fā)的復雜性而創(chuàng)建的。Spring使用的是基本的JavaBean來完成以前只可能由EJB完成的事情。然而,Spring的用途不僅僅限于服務器端的開發(fā)
    2021-10-10
  • java/word+fusionchart生成圖表深入分析

    java/word+fusionchart生成圖表深入分析

    本文將以java/word+fusionchart生成圖表問題深入解析,有興趣的朋友可以參考下
    2012-11-11
  • JAVA連接到SQLserver的步驟方法以及遇到的問題

    JAVA連接到SQLserver的步驟方法以及遇到的問題

    java相對于其他語言(例如c,c++等)連接數據庫要方便得多,下面這篇文章主要給大家介紹了關于JAVA連接到SQLserver的步驟方法及遇到的問題,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • java 實現局域網文件傳輸的實例

    java 實現局域網文件傳輸的實例

    這篇文章主要介紹了java 實現局域網文件傳輸的實例的相關資料,這里提供了實現代碼可以幫助大家理解TCP及文件讀寫的知識,需要的朋友可以參考下
    2017-07-07
  • SpringBoot如何自定義starter

    SpringBoot如何自定義starter

    這篇文章主要介紹了SpringBoot如何自定義starter,Springboot的出現極大的簡化了開發(fā)人員的配置,而這之中的一大利器便是springboot的starter,starter是springboot的核心組成部分,下面來看看集體引用過程吧
    2022-01-01

最新評論