ジャクソンフレームワークの高レベルのアプリケーション

Jacksonは現在、jsonをシリアル化および逆シリアル化するために広く使用されているJavaオープンソースフレームワークです。ジャクソンコミュニティは比較的活発で、更新速度は比較的速いです。Githubの統計から、ジャクソンは最も人気のあるjsonパーサーの1つです。SpringMVCのデフォルトのjsonパーサーはJacksonです。ジャクソンには多くの利点があります。ジャクソンはより少ないjarパッケージに依存しており、使いやすいです。Gsonなどの他のJavajsonフレームワークと比較して、Jacksonは大きなjsonファイルをより高速に解析します。Jacksonは実行時に占有するメモリが少なく、パフォーマンスが向上します。Jacksonには柔軟なAPIがあり、簡単に拡張およびカスタマイズできます。

Jacksonの1.xバージョンのパッケージ名はorg.codehaus.jacksonです。2.xバージョンにアップグレードすると、パッケージ名はcom.fasterxml.jacksonになります。この記事で説明する内容は、最新のJacksonバージョン2.9に基づいています。 .1。

ジャクソンのコアモジュールは3つの部分で構成されています。

コアパッケージであるjackson-coreは、「ストリーミングモード」分析に基づいた関連APIを提供します。これには、JsonPaserとJsonGeneratorが含まれます。Jacksonの内部実装は、高性能ストリーミングモードAPIのJsonGeneratorとJsonParserを介してjsonを生成および解析することです。
アノテーションパッケージのjackson-annotationsは、標準のアノテーション関数を提供します。
データバインディングパッケージのjackson-databindは、「オブジェクトバインディング」分析(ObjectMapper)および「ツリーモデル」分析関連API(JsonNode)に基づく関連APIを提供します。オブジェクトバインディング分析用のAPIとツリーモデル分析用のAPIは、「ストリームモード」に基づく分析用のAPIに依存しています。
ジャクソンの一般的な状況を理解した後、ジャクソンの基本的な使用法を以下に紹介します。

ジャクソンの基本的な使い方

JacksonのコアモジュールjarパッケージをJavaコードで使用する場合は、pom.xmlに次の情報を追加する必要があります。

リスト1.pom.xmlのJackson構成情報

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

jackson-databindは、jackson-coreとjackson-annotationsに依存します。jackson-databindが追加された後、jackson-coreとjackson-annotationsもJavaプロジェクトに追加されます。関連する依存関係を追加した後、Jacksonを使用できます。

ObjectMapperの使用

Jacksonで最も一般的に使用されるAPIは、「オブジェクトバインディング」に基づくObjectMapperです。以下は、ObjectMapperの使用の簡単な例です。

ObjectMapper mapper = new ObjectMapper();
Person person = new Person();
person.setName("Tom");
person.setAge(40);
String jsonString = mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(person);
Person deserializedPerson = mapper.readValue(jsonString, Person.class);

ObjectMapperは、writeValueシリーズメソッドを介してjavaオブジェクトをjsonにシリアル化し、jsonをさまざまな形式(文字列(writeValueAsString)、バイト配列(writeValueAsString)、ライター、ファイル、OutStream、およびDataOutput)で格納します。

ObjectMapperは、readValueシリーズのメソッドを使用して、文字列、バイト配列、リーダー、ファイル、URL、InputStreamなどのさまざまなデータソースからjsonをJavaオブジェクトに逆シリアル化します。

情報構成

writeValueを呼び出す前、またはreadValueメソッドを呼び出す前に、ObjectMapperの関連する構成情報を設定する必要がある場合がよくあります。構成情報は、Javaオブジェクトのすべての属性に適用されます。例は次のとおりです。

リスト3.構成情報の使用例

//在反序列化时忽略在 json 中存在但 Java 对象不存在的属性
 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
    false);
 //在序列化时日期格式默认为 yyyy-MM-dd'T'HH:mm:ss.SSSZ
 mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
 //在序列化时忽略值为 null 的属性
 mapper.setSerializationInclusion(Include.NON_NULL);
 //忽略值为默认值的属性
 mapper.setDefaultPropertyInclusion(Include.NON_DEFAULT);

構成情報の詳細については、JacksonのDeserializationFeature、SerializationFeature、およびIncludeを参照してください。

ジャクソンの注釈の使用

Jacksonは、デフォルトのメソッドに従ってJavaオブジェクトをシリアル化および逆シリアル化します。実際のニーズに応じてデフォルトのメソッドを柔軟に調整する場合は、Jacksonのアノテーションを使用できます。一般的に使用される注釈と使用法は次のとおりです。

表1.ジャクソンの一般的な注釈

注釈 使用法
@JsonProperty 属性に使用され、シリアル化時に属性の名前が別の名前に変換されます。例:@JsonProperty(“ birth_ d ate”)private Date birthDate;
@JsonFormat プロパティまたはメソッドに使用され、シリアル化時にプロパティの形式を指定された形式に変換します。例:@JsonFormat(timezone =“ GMT + 8”、pattern =“ yyyy-MM-dd HH:mm”)public Date getBirthDate()
@JsonPropertyOrder クラスに使用され、シリアル化するときにjsonのプロパティの順序を指定します。例:@JsonPropertyOrder({"birth_Date"、 "name"})public class Person
@JsonCreator 構築メソッドに使用され、@ JsonPropertyと組み合わせて使用​​され、パラメーターを使用した構築メソッドに適しています。例:@JsonCreator public Person(@JsonProperty(“ name”)String name){…}
@JsonAnySetter プロパティまたはメソッドの場合、逆シリアル化されていないプロパティの名前と値をキー値として設定し、マップに格納します@JsonAnySetter public void set(String key、Object value){map.put(key、value);}
@JsonAnyGetter シリアル化されていないすべての属性を取得するメソッドで使用されますpublicMap <string、object> any(){return map;}

Jacksonの基本的な使用法を理解した後、その高レベルのアプリケーションのいくつかを以下に詳細に紹介します。

ジャクソンのハイエンドアプリケーション

フォーマット処理(日付フォーマットを含む)

ジャクソンは、さまざまな種類の日付をさまざまな方法で処理します。

日付タイプjava.util.Calendar、java.util.GregorianCalendar、java.sql.Date、java.util.Date、java.sql.Timestampの場合、形式が指定されていない場合は、jsonでシリアル化されます。ファイルデータ。明らかに、このデフォルトのフォーマットは読みにくく、フォーマットの変換が必要です。ジャクソンには、日付形式を変換する方法がたくさんあります。
アノテーションメソッドについては、「The Use ofJacksonAnnotations」の@JsonFormatの例を参照してください。
ObjectMapperモードで、ObjectMapperのメソッドsetDateFormatを呼び出して、データを指定された形式の文字列型データにシリアル化します。
日付型java.time.LocalDateの場合、コードmapper.registerModule(new JavaTimeModule())を追加し、対応する依存jarパッケージを追加する必要もあります。
リスト4. JSR310構成情報

<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.1</version>
</dependency>

Jackson 2.5より前のバージョンでは、コードobjectMapper.registerModule(new JSR310Module())を追加する必要があります。

日付型org.joda.time.DateTimeの場合、コードmapper.registerModule(new JodaModule())を追加し、対応する依存jarパッケージを追加する必要もあります。
リスト5.Joda構成情報

 <dependency>
 <groupId>com.fasterxml.jackson.datatype</groupId>
 <artifactId>jackson-datatype-joda</artifactId>
 <version>2.9.1</version>
 </dependency>

一般的な逆シリアル化
Jacksonは、一般的な逆シリアル化も適切にサポートします。

Listタイプの場合、constructCollectionTypeメソッドを呼び出してシリアル化するか、TypeReferenceを作成してシリアル化することができます。
リスト6.一般的な使用例をリストする

CollectionType javaType = mapper.getTypeFactory()
 .constructCollectionType(List.class, Person.class);
 List<Person> personList = mapper.readValue(jsonInString, javaType);
 List<Person> personList = mapper.readValue(jsonInString, new
    TypeReference<List<Person>>(){
    
    });

マップタイプの場合、実装はListの実装と同様です。
リスト7.マップの一般的な使用例

//第二参数是 map 的 key 的类型,第三参数是 map 的 value 的类型
 MapType javaType =
    mapper.getTypeFactory().constructMapType(HashMap.class,String.class,
    Person.class);
 Map<String, Person> personMap = mapper.readValue(jsonInString,
    javaType);
 Map<String, Person> personMap = mapper.readValue(jsonInString, new
    TypeReference<Map<String, Person>>() {
    
    });

ArrayとCollectionの処理は、ListとMapに似ているため、ここでは詳しく説明しません。

属性の視覚化

Javaオブジェクトのすべての属性がシリアル化および逆シリアル化されます。つまり、すべての属性が視覚化されるわけではありません。デフォルトの属性視覚化ルールは次のとおりです。

属性修飾子がパブリックの場合、属性はシリアル化および逆シリアル化できます。
プロパティの修飾子がパブリックではないが、そのgetterメソッドとsetterメソッドがパブリックである場合、プロパティはシリアル化および逆シリアル化できます。シリアル化にはgetterメソッドが使用され、逆シリアル化にはsetterメソッドが使用されるためです。
プロパティにパブリックセッターメソッドのみがあり、パブリックゲッターメソッドがない場合、プロパティは逆シリアル化にのみ使用できます。
デフォルトのプロパティ視覚化ルールを変更する場合は、ObjectMapperメソッドsetVisibilityを呼び出す必要があります。

次の例では、修飾子が保護されている属性名をシリアル化および逆シリアル化することもできます。

リスト8.属性の視覚化の例

mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
 public class Person {
    
    
public int age;
 protected String name;
}
 PropertyAccessor 支持的类型有 ALL,CREATOR,FIELD,GETTER,IS_GETTER,NONE,SETTER
 Visibility 支持的类型有 A
    NY,DEFAULT,NON_PRIVATE,NONE,PROTECTED_AND_PUBLIC,PUBLIC_ONLY

属性フィルタリング

Javaオブジェクトをjsonにシリアル化する場合、一部のプロパティをフィルターで除外し、jsonに表示しないようにする必要があります。Jacksonには複数の実装メソッドがあります。

アノテーションメソッド。@ JsonIgnoreを使用して単一のプロパティをフィルタリングするか、@ JsonIgnorePropertiesを使用して複数のプロパティをフィルタリングできます。例は次のとおりです。
リスト9.プロパティフィルタリングの例1

@JsonIgnore
 public int getAge()
 @JsonIgnoreProperties(value = {
    
     "age","birth_date" })
 public class Person

addMixInメソッドには@JsonIgnorePropertiesアノテーションが付けられています。
addMixInメソッドのシグネチャは次のとおりです。

public ObjectMapper addMixIn(Class <?> target、Class <?> mixinSource);

addMixInメソッドの機能は、mixinSourceインターフェイスまたはクラスのアノテーションを使用して、ターゲットまたはターゲットサブタイプのアノテーションを上書きすることです。ixInで設定

Person peixIn @JsonIgnoreProperties( "name")が書き換えられ、最後に無視されるプロパティはnameです。最終的に生成されるjsonは次のとおりです。

{“ birthDate”:” 2017/09/13”、” age”:40}

SimpleBeanPropertyFilterメソッド。この方法は、前の2つの方法よりも柔軟性があり、複雑です。
まず、@ JsonFilterクラスまたはインターフェイスを設定し、次にaddMixInを設定し、@ JsonFilterをJavaオブジェクトに適用し、最後にSimpleBeanPropertyFilterのserializeAllExceptメソッドを呼び出すか、SimpleBeanPropertyFilterのserializeAsFieldメソッドをオーバーライドして関連するプロパティをフィルタリングする必要があります。例は次のとおりです。

リスト11.属性フィルタリングの例3

//设置 Filter 类或接口
 @JsonFilter("myFilter")
public interface MyFilter {
    
    }
//设置 addMixIn
mapper.addMixIn(Person.class, MyFilter.class);
//调用 SimpleBeanPropertyFilter 的 serializeAllExcept 方法
 SimpleBeanPropertyFilter newFilter =
 SimpleBeanPropertyFilter.serializeAllExcept("age");
//或重写 SimpleBeanPropertyFilter 的 serializeAsField 方法
 SimpleBeanPropertyFilter newFilter = new SimpleBeanPropertyFilter() {
    
    
 @Override
 public void serializeAsField(Object pojo, JsonGenerator jgen,
 SerializerProvider provider, PropertyWriter writer)
 throws Exception {
    
    
 if (!writer.getName().equals("age")) {
    
    
 writer.serializeAsField(pojo, jgen, provider);
 }
 }
 };
//设置 FilterProvider
 FilterProvider filterProvider = new SimpleFilterProvider()
 .addFilter("myFilter", newFilter);
 mapper.setFilterProvider(filterProvider).writeValueAsString(person);

カスタムシリアル化と逆シリアル化

Jacksonのデフォルトのシリアル化および逆シリアル化クラスが実際のニーズを満たすことができない場合は、新しいシリアル化および逆シリアル化クラスをカスタマイズできます。

カスタムシリアル化クラス。カスタムシリアル化クラスは、StdSerializerまたはJsonSerializerを直接または間接的に継承する必要があり、JsonGeneratorを使用してjsonを生成し、serializeメソッドをオーバーライドする必要があります。例は次のとおりです。
リスト12.カスタムシリアル化

 public class CustomSerializer extends StdSerializer<Person> {
    
    
 @Override
 public void serialize(Person person, JsonGenerator jgen,
 SerializerProvider provider) throws IOException {
    
    
 jgen.writeStartObject();
 jgen.writeNumberField("age", person.getAge());
 jgen.writeStringField("name", person.getName());
 jgen.writeEndObject();
 }
 }

JsonGeneratorには、writeArray、writeTreeなどの複雑なタイプのjsonの生成をサポートするためのさまざまな書き込みメソッドがあります。JsonGeneratorを個別に作成する場合は、JsonFactory()のcreateGeneratorを使用できます。

カスタム逆シリアル化クラス。カスタムデシリアライズクラスは、StdDeserializerまたはStdDeserializerを直接または間接的に継承する必要があり、JsonParserを使用してjsonを読み取り、デシリアライズメソッドをオーバーライドする必要があります。例は次のとおりです。
リスト13.カスタムシリアル化

public class CustomDeserializer extends StdDeserializer<Person> {
    
    
 @Override
 public Person deserialize(JsonParser jp, DeserializationContext ctxt)
 throws IOException, JsonProcessingException {
    
    
 JsonNode node = jp.getCodec().readTree(jp);
 Person person = new Person();
 int age = (Integer) ((IntNode) node.get("age")).numberValue();
 String name = node.get("name").asText();
 person.setAge(age);
 person.setName(name);
return person;
}
 }

JsonParserは、isClosed()、nextToken()、getValueAsString()など、json情報を読み取るための多くのメソッドを提供します。JsonParserを個別に作成する場合は、JsonFactory()のcreateParserを使用できます。

カスタムシリアル化クラスとカスタム逆シリアル化クラスを定義します。これらをプログラムで呼び出す場合は、ObjectMapperモジュールにも登録する必要があります。例は次のとおりです。
リスト14.モジュールの登録例

SimpleModule module = new SimpleModule("myModule");
 module.addSerializer(new CustomSerializer(Person.class));
 module.addDeserializer(Person.class, new CustomDeserializer());
 mapper.registerModule(module);
 也可通过注解方式加在 java 对象的属性,方法或类上面来调用它们,
 @JsonSerialize(using = CustomSerializer.class)
 @JsonDeserialize(using = CustomDeserializer.class)
 public class Person

ツリーモデルの処理

Jacksonは、jsonを生成および解析するためのツリーモデルも提供します。jsonの一部のプロパティを変更またはアクセスする場合は、ツリーモデルが適しています。ツリーモデルは、JsonNodeノードで構成されています。ObjectNodeはプログラムでよく使用され、ObjectNodeはJsonNodeを継承します。例は次のとおりです。

リスト15.ObjectNodeはjsonの例を生成して解析します

 ObjectMapper mapper = new ObjectMapper();
 //构建 ObjectNode
 ObjectNode personNode = mapper.createObjectNode();
 //添加/更改属性
 personNode.put("name","Tom");
 personNode.put("age",40);
 ObjectNode addressNode = mapper.createObjectNode();
 addressNode.put("zip","000000");
 addressNode.put("street","Road NanJing");
 //设置子节点
 personNode.set("address",addressNode);
 //通过 path 查找节点
 JsonNode searchNode = personNode.path("street ")//删除属性
 ((ObjectNode) personNode).remove("address");
 //读取 json
 JsonNode rootNode = mapper.readTree(personNode.toString());
 //JsonNode 转换成 java 对象
 Person person = mapper.treeToValue(personNode, Person.class);
 //java 对象转换成 JsonNode
 JsonNode node = mapper.valueToTree(person);

総括する

この記事では、最初に他のJava jsonフレームワークとの比較を通じてJacksonの利点を紹介し、Jacksonのコアモジュールの構成と各部分の役割について説明します。次に、この記事では、例を通してJacksonの基本的な使用法を説明し、ObjectMapperの書き込みメソッドと読み取りメソッド、ObjectMapperの構成情報設定、およびjackson-annotationsパッケージでのアノテーションの使用法を紹介します。最後に、この記事では、ジャクソンの高レベルの使用法を詳細に紹介します。これもこの記事の焦点です。これらの高レベルの使用法には、さまざまなタイプの日付形式処理(通常の日付タイプ、jdk 8日付タイプ、joda日付タイプ)、リストやマップなどの汎用タイプの逆シリアル化、属性の視覚的管理、および3つのJackson属性のフィルタリング方法、実装が含まれます。カスタムのシリアル化と逆シリアル化、およびツリーモデルの使用について説明します。この記事の体系的な説明を通して、読者はジャクソンをより深く、より包括的に理解することができると私は信じています。

おすすめ

転載: blog.csdn.net/qq_40093255/article/details/113682338