Jackson數據處理及綁定


獲取

Maven的

該軟件包的功能包含在Java包中com.fasterxml.jackson.databind,可以使用以下Maven依賴項來使用:

< properties > ...
  <! -盡可能使用最新版本。- > < jackson .version> 2.9.7 </ jackson .version> ... </ properties >  < dependencies > ... < 依賴 > < groupId > com.fasterxml.jackson.core </ groupId > < artifactId > jackson-databind </ artifactId > < version > $ {jackson.version} </ version > </ dependency > ... </ dependencies >

由於包依賴於jackson-corejackson-annotations包,因此如果不使用Maven,則需要下載這些包; 並且您可能還希望將它們添加為Maven依賴項以確保使用兼容版本。如果是這樣,還要添加:

< dependencies > ... < dependency > <! -注意:core-annotations版本xy0通常與  版本xy1,xy2等兼容(相同)- > < groupId > com.fasterxml.jackson.core </ groupId > < artifactId > jackson-annotations </ artifactId > < version > $ {jackson.version} </ version > </ dependency > < 依賴 > < groupId > com.fasterxml.jackson.core </ groupId > < artifactId > jackson-core </ artifactId > < version > $ {jackson.version} </ version > </ dependency > ... < dependencies >

但請注意,這是可選的,只有在jackson核心依賴關系通過傳遞依賴關系存在沖突時才有必要。

非Maven的

對於非Maven用例,您可以從Central Maven存儲庫下載jar 

Databind jar也是一個功能性的OSGi包,具有適當的導入/導出聲明,因此它可以在OSGi容器上使用。


使用

可以從Jackson-docs存儲庫中找到更全面的文檔以及來自此項目的Wiki但這里有簡要的介紹性教程,建議閱讀順序。

1分鍾教程:POJO到JSON並返回

最常見的用法是使用JSON,並從中構造一個Plain Old Java Object(“POJO”)。那么讓我們從那里開始。簡單的2屬性POJO像這樣:

//注意:也可以使用getter / setter; 這里我們直接使用公共字段: public  class  MyValue {  public  String name; 公共 INT年齡; //注意:如果使用getter / setter,可以保留字段`protected`或`private` }

我們需要一個com.fasterxml.jackson.databind.ObjectMapper用於所有數據綁定實例,所以讓我們構造一個:

ObjectMapper mapper =  new  ObjectMapper(); //創建一次,重用

默認實例適合我們使用 - 稍后我們將了解如何在必要時配置映射器實例。用法很簡單:

MyValue value = mapper.readValue(new File("data.json"), MyValue.class);
// or:
value = mapper.readValue(new URL("http://some.com/api/entry.json"), MyValue.class);
// or:
value = mapper.readValue("{\"name\":\"Bob\", \"age\":13}", MyValue.class);

如果我們想寫JSON,我們會反過來:

mapper.writeValue(new File("result.json"), myResultObject);
// or:
byte[] jsonBytes = mapper.writeValueAsBytes(myResultObject);
// or:
String jsonString = mapper.writeValueAsString(myResultObject);

到現在為止還挺好?

3分鍾教程:通用集合,樹模型

除了處理簡單的Bean風格的POJO之外,您還可以處理JDK ListMaps:

Map<String, Integer> scoreByName = mapper.readValue(jsonSource, Map.class);
List<String> names = mapper.readValue(jsonSource, List.class);

// and can obviously write out as well
mapper.writeValue(new File("names.json"), names);

只要JSON結構匹配,類型就很簡單。如果您有POJO值,則需要指明實際類型(注意:對於具有Listetc類型的POJO屬性,這不是必需的):

Map<String, ResultValue> results = mapper.readValue(jsonSource,
   new TypeReference<Map<String, ResultValue>>() { } );
// why extra work? Java Type Erasure will prevent type detection otherwise

(注意:無論通用類型如何,序列化都不需要額外的工作)

可是等等!還有更多!

雖然處理Maps,Lists和其他“簡單”對象類型(字符串,數字,布爾值)可能很簡單,但對象遍歷可能很麻煩。這就是Jackson's Tree模型可以派上用場的地方:

//可以讀作通用的JsonNode,如果它可以是Object或Array; 或者, //如果已知為Object,則為ObjectNode,如果是array,ArrayNode等: ObjectNode root = mapper.readTree("stuff.json");
String name = root.get("name").asText();
int age = root.get("age").asInt();
//也可以修改:這會將子對象添加為屬性'other',設置屬性'root.with("other").put("type", "student");
String json = mapper.writeValueAsString(root);
//與上面一樣,我們最終得到像'json'字符串:// {
//   "name" : "Bob", "age" : 13,
//   "other" : {
//      "type" : "student"
//   }
// }

樹模型比數據綁定更方便,特別是在結構高度動態或不能很好地映射到Java類的情況下。

5分鍾教程:流解析器,生成器

數據綁定(往/來自POJO)可以方便; 並且像Tree模型一樣靈活,還有一個可用的規范處理模型:增量(又稱“流”)模型。它是數據綁定和樹模型都構建的底層處理模型,但它也向需要最終性能和/或控制解析或生成細節的用戶公開。

有關深入解釋,請查看Jackson Core組件但是,讓我們看一個簡單的預告片,以激發你的胃口。

JsonFactory f = mapper.getFactory(); // may alternatively construct directly too

// First: write simple JSON output
File jsonFile = new File("test.json");
JsonGenerator g = f.createGenerator(jsonFile);
// write JSON: { "message" : "Hello world!" }
g.writeStartObject();
g.writeStringField("message", "Hello world!");
g.writeEndObject();
g.close();

// Second: read file back
JsonParser p = f.createParser(jsonFile);

JsonToken t = p.nextToken(); // Should be JsonToken.START_OBJECT
t = p.nextToken(); // JsonToken.FIELD_NAME
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();

10分鍾教程:配置

您可能會使用兩種入門級配置機制: 功能注釋

常用功能

以下是您最有可能需要了解的配置功能示例。

讓我們從更高級別的數據綁定配置開始。

// SerializationFeature用於更改JSON的編寫方式 //啟用標准縮進(“漂亮打印”):mapper.enable(SerializationFeature.INDENT_OUTPUT);
//
允許序列化“空”POJO(沒有要序列化的屬性) //(沒有這個設置,在這些情況下拋出異常)mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS); //編寫java.util.Date,Calendar as number(timestamp):mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// DeserializationFeature用於更改如何將JSON讀取為POJO: //在遇到未知屬性時阻止異常:mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//
允許將JSON空字符串(“”)強制為null對象值:
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

此外,您可能需要更改一些低級JSON解析,生成詳細信息:

//用於配置解析設置的JsonParser.Feature: //允許JSON中的C / C ++樣式注釋(非標准,默認禁用) //(注意:使用Jackson 2.5,還有`mapper.enable(feature)`/`mapper.disable(feature)`)mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
//
允許在JSON: mapper中允許(非標准)不帶引號的字段名稱配置( JsonParser 功能 ALLOW_UNQUOTED_FIELD_NAMES); //允許使用撇號(單引號),非標准mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
//
用於配置低級JSON生成的JsonGenerator.Feature: //強制轉義非ASCII字符:
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

Jackson功能頁面上介紹了全套功能

注釋:更改屬性名稱

最簡單的基於注釋的方法是使用如下@JsonProperty注釋:

public  class  MyBean { private  String _name; //沒有注釋,我們得到“theName”,但我們想要“name”:  @JsonProperty("name")
   public String getTheName() { return _name; }
//注意:只需在getter或setter上添加注釋即可; //所以我們可以省略它 public void setTheName(String n) { _name = n; }
}

還有其他機制可用於系統命名更改:有關詳細信息,請參閱自定義命名約定

另請注意,您可以使用“ 混合注釋”來關聯所有注釋。

注釋:忽略屬性

有兩個主要注釋可用於忽略屬性:@JsonIgnore對於單個屬性; @JsonIgnoreProperties為每班定義

//意味着如果我們在JSON中看到“foo”或“bar”,它們將被靜靜地跳過 //無論POJO是否具有這樣的屬性
@JsonIgnoreProperties({ "foo", "bar" })
public class MyBean
{
   // will not be written as JSON; nor assigned from JSON:
   @JsonIgnore
   public String internal;

   // no annotation, public field is read/written normally
   public String external;

   @JsonIgnore
   public void setCode(int c) { _code = c; }

   // note: will also be ignored because setter has annotation!
   public int getCode() { return _code; }
}

與重命名一樣,請注意注釋在匹配字段,getter和setter之間“共享”:如果只有一個@JsonIgnore,則會影響其他字段但也可以使用“拆分”注釋,例如:

public  class  ReadButDontWriteProps { private  String _name; @JsonProperty  public  void  setNameString  n){_ name = n; } @JsonIgnore  public  String  getName(){ return _name; } }

在這種情況下,不會寫出“name”屬性(因為'getter'被忽略); 但如果從JSON中找到“name”屬性,它將被分配給POJO屬性!

有關在寫出JSON時忽略屬性的所有可能方法的更完整說明,請選中“過濾屬性”一文。

注釋:使用自定義構造函數

與許多其他數據綁定包不同,Jackson不要求您定義“默認構造函數”(不帶參數的構造函數)。雖然它將使用一個,如果沒有其他可用,您可以輕松定義使用參數構造函數:

public class CtorBean
{
  public final String name; public final int age;

  @JsonCreator // constructor can be public, private, whatever
  private CtorBean(@JsonProperty("name") String name,
    @JsonProperty("age") int age)
  {
      this.name = name;
      this.age = age;
  }
}

構造函數在支持使用Immutable對象方面特別有用 

或者,您也可以定義“工廠方法”:

public class FactoryBean
{
    // fields etc omitted for brewity

    @JsonCreator
    public static FactoryBean create(@JsonProperty("name") String name) {
      // construct and return an instance
    }
}

請注意,使用“創建者方法”(@JsonCreator帶有@JsonProperty注釋參數)並不排除使用setter:您可以將構造函數/工廠方法中的屬性與通過setter設置的屬性或直接使用字段進行混合和匹配。

教程:更高級的東西,轉換

傑克遜的一個有用(但不是非常廣為人知)的特征是它能夠進行任意POJO到POJO的轉換。從概念上講,您可以將轉換視為兩個步驟的序列:首先,將POJO編寫為JSON,然后將JSON綁定到另一種POJO中。實現只是跳過實際生成的JSON,並使用更有效的中間表示。

轉換在任何兼容類型之間工作,並且調用非常簡單:

ResultType結果=映射器convertValue(sourceObject,與resultType 類);

並且只要源和結果類型兼容 - 也就是說,如果to-JSON,from-JSON序列將成功 - 事情將“正常工作”。但是這里有幾個可能有用的用例:

//從List <Integer>轉換為int []  List<Integer> sourceList = ...;
int[] ints = mapper.convertValue(sourceList, int[].class);
//
將POJO轉換為Map! Map<String,Object> propertyMap = mapper.convertValue(pojoValue, Map.class);
//
...並返回 PojoType pojo = mapper.convertValue(propertyMap, PojoType.class); //解碼Base64!(缺省字節[]表示是base64編碼字串)
String base64 = "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz";
byte[] binary = mapper.convertValue(base64, byte[].class);

基本上,Jackson可以替代許多Apache Commons組件,用於base64編碼/解碼和處理“dyna beans”(映射到/來自POJO)等任務。

貢獻!

我們希望得到您的貢獻,無論是以錯誤報告,增強請求(RFE),文檔或代碼補丁的形式。以上所有的主要機制是GitHub Issues系統

代碼貢獻的基本規則

實際上只有一個主要規則,即接受任何代碼貢獻,我們需要從作者那里獲得一份填充的貢獻者許可協議(CLA)。一個CLA對於任何數量的貢獻都足夠了,但我們需要一個。或者說,使用我們代碼的公司需要它。這讓他們的律師對開源使用不那么不滿。

核心組件對依賴性的限制

所謂的核心組件(流式api,jackson-annotations和jackson-databind)還存在一個額外的限制:除了以下內容外,不允許任何額外的依賴:

  • 核心組件可能依賴於受支持的JDK中包含的任何方法
    • 截至Jackson 2.4及以上版本的最低JDK版本為1.6(基線為2.3及更早版本為1.5)
  • Jackson-databind(這個包)取決於其他兩個(注釋,流)。

這意味着任何必須依賴其他API或庫的東西都需要構建為擴展,通常是Jackson模塊。


與Jackson 1.x的不同之處

項目包含2.0及更高版本:最后(1.x)版本的源代碼1.9,可在 Jackson-1 repo上獲得。

與1.x“mapper”jar相比的主要差異是:

  • Maven構建而不是Ant
  • Java包現在com.fasterxml.jackson.databind(而不是org.codehaus.jackson.map


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM