亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

目錄
03、更高級的配置
04、處理日期格式
05、字段過濾
06、自定義序列化和反序列化
07、結語
首頁 Java Java基礎 自認為最牛的 Java JSON 解析器:Jackson

自認為最牛的 Java JSON 解析器:Jackson

Dec 16, 2020 am 09:48 AM
java 後端

java基礎教學欄位介紹Java JSON的解析器

自認為最牛的 Java JSON 解析器:Jackson

##推薦(免費):java基礎教學

在當今的程式設計世界裡,JSON 已經成為將資訊從客戶端傳輸到伺服器端的首選協(xié)議,可以好不誇張的說,XML 就是那個被拍死在沙灘上的前浪。

很不幸的是,JDK 沒有 JSON 函式庫,不知道為什麼不搞一下。 Log4j 的時候,為了競爭,還推出了 java.util.logging,雖然最後也沒多少人用。

Java 之所以牛逼,很大的功勞在於它的生態(tài)非常完備,JDK 沒有JSON 庫,第三方類庫有啊,還挺不錯,比如說本篇的豬腳——Jackson, GitHub 上標星6.1k,Spring Boot 的預設JSON 解析器。

要怎麼證明這一點呢?

當我們透過 starter 新建一個 Spring Boot 的 Web 專案後,就可以在 Maven 的依賴項中看到 Jackson 的身影。

自認為最牛的 Java JSON 解析器:Jackson

Jackson 有許多優(yōu)點:

    解析大檔案的速度比較快;
  • 執(zhí)行時佔用的記憶體比較少,效能更佳;
  • API 很靈活,容易進行擴充和客製化。
Jackson 的核心模組由三個部分組成:

    jackson-core,核心包,提供基於「流模式」解析的相關 API,包括 JsonPaser 和 JsonGenerator。
  • jackson-annotations,註解包,提供標準的註解功能;
  • jackson-databind ,資料綁定包,提供基於「物件綁定」解析的相關API ( ObjectMapper ) 和基於「樹模型」解析的相關API (JsonNode)。
01、引入 Jackson 依賴

要想使用 Jackson,需要在 pom.xml 檔案中加入 Jackson 的依賴。

<dependency>
????<groupid>com.fasterxml.jackson.core</groupid>
????<artifactid>jackson-databind</artifactid>
????<version>2.10.1</version>
</dependency>
jackson-databind 依賴 jackson-core 和 jackson-annotations,所以在新增 jackson-databind 之後,Maven 會自動將 jackson-core 和 jackson-annotations 引入到專案當中。

自認為最牛的 Java JSON 解析器:Jackson

Maven 之所以討人喜歡的一點就在這,能偷偷摸摸地幫我們把該做的做了。

02、使用ObjectMapper

Jackson 最常用的API 就是基於」物件綁定」 的ObjectMapper,它透過writeValue 的系列方法將Java 物件序列化為JSON,並且可以儲存成不同的格式。

  • writeValueAsString(Object value) 方法,將物件儲存成字串
  • writeValueAsBytes(Object value) 方法,將物件儲存成字節(jié)數組
  • writeValue(File resultFile, Object value) 方法,將物件儲存成檔案
來看儲存成字串的程式碼範例:

import?com.fasterxml.jackson.core.JsonProcessingException;
import?com.fasterxml.jackson.databind.ObjectMapper;

/**
?*?微信搜索「沉默王二」,回復?Java
?*
?*?@author?沉默王二
?*?@date?2020/11/26
?*/
public?class?Demo?{
????public?static?void?main(String[]?args)?throws?JsonProcessingException?{
????????Writer?wanger?=?new?Writer("沉默王二",?18);
????????ObjectMapper?mapper?=?new?ObjectMapper();
????????String?jsonString?=?mapper.writerWithDefaultPrettyPrinter()
????????????????.writeValueAsString(wanger);
????????System.out.println(jsonString);
????}
}

class?Writer?{
????private?String?name;
????private?int?age;

????public?Writer(String?name,?int?age)?{
????????this.name?=?name;
????????this.age?=?age;
????}

????public?String?getName()?{
????????return?name;
????}

????public?void?setName(String?name)?{
????????this.name?=?name;
????}

????public?int?getAge()?{
????????return?age;
????}

????public?void?setAge(int?age)?{
????????this.age?=?age;
????}
}
程式輸出結果如下所示:

{
??"name"?:?"沉默王二",
??"age"?:?18
}
不是所有的欄位都支援序列化和反序列化,需要符合以下規(guī)則:

    如果字段的修飾符是public,則該字段可序列化和反序列化(不是標準寫法)。
  • 如果欄位的修飾符不是 public,但它的 getter 方法和 setter 方法是 public,則該欄位可序列化和反序列化。 getter 方法用於序列化,setter 方法用於反序列化。
  • 如果欄位只有 public 的 setter 方法,而無 public 的 getter 方 法,則該欄位只能用於反序列化。
如果想要更改預設的序列化和反序列化規(guī)則,則需要呼叫 ObjectMapper 的

setVisibility() 方法。否則將會拋出 InvalidDefinitionException 異常。

ObjectMapper 透過 readValue 的系列方法從不同的資料來源將 JSON 反序列化為 Java 物件。

  • readValue(String content, Class valueType) 方法,將字串反序列化為Java 物件
  • readValue(byte[ ] src, Class valueType) 方法,將位元組陣列反序列化為Java 物件
  • readValue(File src, Class valueType) 方法,將檔案反序列化為Java 物件
來看將字串反序列化為Java 物件的程式碼範例:

import?com.fasterxml.jackson.core.JsonProcessingException;
import?com.fasterxml.jackson.databind.ObjectMapper;

/**
?*?微信搜索「沉默王二」,回復?Java
?*
?*?@author?沉默王二
?*?@date?2020/11/26
?*/
public?class?Demo?{
????public?static?void?main(String[]?args)?throws?JsonProcessingException?{
????????ObjectMapper?mapper?=?new?ObjectMapper();
????????String?jsonString?=?"{\n"?+
????????????????"??\"name\"?:?\"沉默王二\",\n"?+
????????????????"??\"age\"?:?18\n"?+
????????????????"}";
????????Writer?deserializedWriter?=?mapper.readValue(jsonString,?Writer.class);
????????System.out.println(deserializedWriter);
????}
}

class?Writer{
????private?String?name;
????private?int?age;

????//?getter/setter

????@Override
????public?String?toString()?{
????????return?"Writer{"?+
????????????????"name='"?+?name?+?'\''?+
????????????????",?age="?+?age?+
????????????????'}';
????}
}
程式輸出結果如下所示:

Writer{name='沉默王二',?age=18}
PS:如果反序列化的物件有帶參的建構方法,它必須有一個空的預設建構方法,否則將會拋出

InvalidDefinitionException 一行。

Exception?in?thread?"main"?com.fasterxml.jackson.databind.exc.InvalidDefinitionException:?Cannot?construct?instance?of?`com.itwanger.jackson.Writer`?(no?Creators,?like?default?construct,?exist):?cannot?deserialize?from?Object?value?(no?delegate-?or?property-based?Creator)
?at?[Source:?(String)"{
??"name"?:?"沉默王二",
??"age"?:?18
}";?line:?2,?column:?3]
????at?com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
????at?com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1589)
????at?com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1055)
????at?com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
????at?com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
????at?com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
????at?com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
????at?com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
????at?com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
????at?com.itwanger.jackson.Demo.main(Demo.java:19)
Jackson 最常用的 API 就是基於」物件綁定” 的 ObjectMapper,

ObjectMapper 也可以將 JSON 解析為基於「樹模型」的 JsonNode 對象,來看下面的範例。

import?com.fasterxml.jackson.core.JsonProcessingException;
import?com.fasterxml.jackson.databind.JsonNode;
import?com.fasterxml.jackson.databind.ObjectMapper;

/**
?*?微信搜索「沉默王二」,回復?Java
?*
?*?@author?沉默王二
?*?@date?2020/11/26
?*/
public?class?JsonNodeDemo?{
????public?static?void?main(String[]?args)?throws?JsonProcessingException?{
????????ObjectMapper?mapper?=?new?ObjectMapper();
????????String?json?=?"{?\"name\"?:?\"沉默王二\",?\"age\"?:?18?}";
????????JsonNode?jsonNode?=?mapper.readTree(json);
????????String?name?=?jsonNode.get("name").asText();
????????System.out.println(name);?//?沉默王二
????}
}

借助 TypeReference 可以將 JSON 字符串數組轉成泛型 List,來看下面的示例:

import?com.fasterxml.jackson.core.JsonProcessingException;
import?com.fasterxml.jackson.core.type.TypeReference;
import?com.fasterxml.jackson.databind.ObjectMapper;

import?java.util.List;

/**
?*?微信搜索「沉默王二」,回復?Java
?*
?*?@author?沉默王二
?*?@date?2020/11/26
?*/
public?class?TypeReferenceDemo?{
????public?static?void?main(String[]?args)?throws?JsonProcessingException?{
????????ObjectMapper?mapper?=?new?ObjectMapper();
????????String?json?=?"[{?\"name\"?:?\"沉默王三\",?\"age\"?:?18?},?{?\"name\"?:?\"沉默王二\",?\"age\"?:?19?}]";
????????List<author>?listAuthor?=?mapper.readValue(json,?new?TypeReference<list>>(){});
????????System.out.println(listAuthor);
????}
}
class?Author{
????private?String?name;
????private?int?age;

????//?getter/setter

????//?toString
}</list></author>

03、更高級的配置

Jackson 之所以牛掰的一個很重要的因素是可以實現高度靈活的自定義配置。

在實際的應用場景中,JSON 中常常會有一些 Java 對象中沒有的字段,這時候,如果直接解析的話,會拋出 UnrecognizedPropertyException 異常。

下面是一串 JSON 字符串:

String?jsonString?=?"{\n"?+
????????????????"??\"name\"?:?\"沉默王二\",\n"?+
????????????????"??\"age\"?:?18\n"?+
????????????????"??\"sex\"?:?\"男\(zhòng)",\n"?+
????????????????"}";

但 Java 對象 Writer 中沒有定義 sex 字段:

class?Writer{
????private?String?name;
????private?int?age;

????//?getter/setter
}

我們來嘗試解析一下:

ObjectMapper?mapper?=?new?ObjectMapper();
Writer?deserializedWriter?=?mapper.readValue(jsonString,?Writer.class);

不出意外,拋出異常了,sex 無法識別。

Exception?in?thread?"main"?com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException:?Unrecognized?field?"sex"?(class?com.itwanger.jackson.Writer),?not?marked?as?ignorable?(2?known?properties:?"name",?"age"])
?at?[Source:?(String)"{
??"name"?:?"沉默王二",
??"age"?:?18,
??"sex"?:?"男"
}";?line:?4,?column:?12]?(through?reference?chain:?com.itwanger.jackson.Writer["sex"])

怎么辦呢?可以通過 configure() 方法忽略掉這些“無法識別”的字段。

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,?false);

除此之外,還有其他一些有用的配置信息,來了解一下:

//?在序列化時忽略值為?null?的屬性
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//?忽略值為默認值的屬性
mapper.setDefaultPropertyInclusion(JsonInclude.Include.NON_DEFAULT);

04、處理日期格式

對于日期類型的字段,比如說 java.util.Date,如果不指定格式,序列化后將顯示為 long 類型的數據,這種默認格式的可讀性很差。

{
??"age"?:?18,
??"birthday"?:?1606358621209
}

怎么辦呢?

第一種方案,在 getter 上使用 @JsonFormat 注解。

private?Date?birthday;

//?GMT+8?是指格林尼治的標準時間,在加上八個小時表示你現在所在時區(qū)的時間
@JsonFormat(timezone?=?"GMT+8",?pattern?=?"yyyy-MM-dd?HH:mm:ss")
public?Date?getBirthday()?{
????return?birthday;
}

public?void?setBirthday(Date?birthday)?{
????this.birthday?=?birthday;
}

再來看一下結果:

{
??"age"?:?18,
??"birthday"?:?"2020-11-26?03:02:30"
}

具體代碼如下所示:

ObjectMapper?mapper?=?new?ObjectMapper();
Writer?wanger?=?new?Writer("沉默王二",?18);
wanger.setBirthday(new?Date());
String?jsonString?=?mapper.writerWithDefaultPrettyPrinter()
????????????????.writeValueAsString(wanger);
System.out.println(jsonString);

第二種方案,調用 ObjectMapper 的 setDateFormat() 方法。

ObjectMapper?mapper?=?new?ObjectMapper();
mapper.setDateFormat(StdDateFormat.getDateTimeInstance());
Writer?wanger?=?new?Writer("沉默王二",?18);
wanger.setBirthday(new?Date());
String?jsonString?=?mapper.writerWithDefaultPrettyPrinter()
????????????????.writeValueAsString(wanger);
System.out.println(jsonString);

輸出結果如下所示:

{
??"name"?:?"沉默王二",
??"age"?:?18,
??"birthday"?:?"2020年11月26日?上午11:09:51"
}

05、字段過濾

在將 Java 對象序列化為 JSON 時,可能有些字段需要過濾,不顯示在 JSON 中,Jackson 有一種比較簡單的實現方式。

@JsonIgnore 用于過濾單個字段。

@JsonIgnore
public?String?getName()?{
????return?name;
}

@JsonIgnoreProperties 用于過濾多個字段。

@JsonIgnoreProperties(value?=?{?"age","birthday"?})
class?Writer{
????private?String?name;
????private?int?age;
????private?Date?birthday;
}

06、自定義序列化和反序列化

當 Jackson 默認序列化和反序列化不能滿足實際的開發(fā)需要時,可以自定義新的序列化和反序列化類。

自定義的序列化類需要繼承 StdSerializer,同時重寫 serialize() 方法,利用 JsonGenerator 生成 JSON,示例如下:

/**
?*?微信搜索「沉默王二」,回復?Java
?*
?*?@author?沉默王二
?*?@date?2020/11/26
?*/
public?class?CustomSerializer?extends?StdSerializer<man>?{
????protected?CustomSerializer(Class<man>?t)?{
????????super(t);
????}

????public?CustomSerializer()?{
????????this(null);
????}

????@Override
????public?void?serialize(Man?value,?JsonGenerator?gen,?SerializerProvider?provider)?throws?IOException?{
????????gen.writeStartObject();
????????gen.writeStringField("name",?value.getName());
????????gen.writeEndObject();
????}
}

class?Man{
????private?int?age;
????private?String?name;

????public?Man(int?age,?String?name)?{
????????this.age?=?age;
????????this.name?=?name;
????}

????public?int?getAge()?{
????????return?age;
????}

????public?void?setAge(int?age)?{
????????this.age?=?age;
????}

????public?String?getName()?{
????????return?name;
????}

????public?void?setName(String?name)?{
????????this.name?=?name;
????}
}</man></man>

定義好自定義序列化類后,要想在程序中調用它們,需要將其注冊到 ObjectMapper 的 Module 中,示例如下所示:

ObjectMapper?mapper?=?new?ObjectMapper();
SimpleModule?module?=
????????new?SimpleModule("CustomSerializer",?new?Version(1,?0,?0,?null,?null,?null));
module.addSerializer(Man.class,?new?CustomSerializer());
mapper.registerModule(module);
Man?man?=?new?Man(?18,"沉默王二");
String?json?=?mapper.writeValueAsString(man);
System.out.println(json);

程序輸出結果如下所示:

{"name":"沉默王二"}

自定義序列化類 CustomSerializer 中沒有添加 age 字段,所以只輸出了 name 字段。

再來看一下自定義的反序列化類,繼承 StdDeserializer,同時重寫 deserialize() 方法,利用 JsonGenerator 讀取 JSON,示例如下:

public?class?CustomDeserializer?extends?StdDeserializer<woman>?{
????protected?CustomDeserializer(Class>?vc)?{
????????super(vc);
????}

????public?CustomDeserializer()?{
????????this(null);
????}

????@Override
????public?Woman?deserialize(JsonParser?p,?DeserializationContext?ctxt)?throws?IOException,?JsonProcessingException?{
????????JsonNode?node?=?p.getCodec().readTree(p);
????????Woman?woman?=?new?Woman();
????????int?age?=?(Integer)?((IntNode)?node.get("age")).numberValue();
????????String?name?=?node.get("name").asText();
????????woman.setAge(age);
????????woman.setName(name);
????????return?woman;
????}
}
class?Woman{
????private?int?age;
????private?String?name;

????public?Woman()?{
????}

????//?getter/setter

????@Override
????public?String?toString()?{
????????return?"Woman{"?+
????????????????"age="?+?age?+
????????????????",?name='"?+?name?+?'\''?+
????????????????'}';
????}
}</woman>

通過 JsonNode 把 JSON 讀取到一個樹形結構中,然后通過 JsonNode 的 get 方法將對應字段讀取出來,然后生成新的 Java 對象,并返回。

定義好自定義反序列化類后,要想在程序中調用它們,同樣需要將其注冊到 ObjectMapper 的 Module 中,示例如下所示:

ObjectMapper?mapper?=?new?ObjectMapper();
SimpleModule?module?=
????????new?SimpleModule("CustomDeserializer",?new?Version(1,?0,?0,?null,?null,?null));
module.addDeserializer(Woman.class,?new?CustomDeserializer());
mapper.registerModule(module);
String?json?=?"{?\"name\"?:?\"三妹\",?\"age\"?:?18?}";
Woman?woman?=?mapper.readValue(json,?Woman.class);
System.out.println(woman);

程序輸出結果如下所示:

Woman{age=18,?name='三妹'}

07、結語

哎呀,好像不錯哦,Jackson 絕對配得上“最牛掰”這三個字,雖然有點虛。如果只想簡單的序列化和反序列化,使用 ObjectMapper 的 write 和 read 方法即可。

如果還想更進一步的話,就需要對 ObjectMapper 進行一些自定義配置,或者加一些注解,以及直接自定義序列化和反序列化類,更貼近一些 Java 對象。

需要注意的是,對日期格式的字段要多加小心,盡量不要使用默認配置,可讀性很差。

好了,通過這篇文章的系統(tǒng)化介紹,相信你已經完全摸透 Jackson 了,我們下篇文章見。

PS:如果你恰好需要一份 Java 精進路線的話,我這里有一份,我差不多花了 3 天的時間整理的,還挺受歡迎的,已經 2000 多贊了,每個階段都很詳細。

相關免費學習推薦:php編程(視頻)

以上是自認為最牛的 Java JSON 解析器:Jackson的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發(fā)現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Laravel 教程
1597
29
PHP教程
1488
72
VSCODE設置。 JSON位置 VSCODE設置。 JSON位置 Aug 01, 2025 am 06:12 AM

settings.json文件位於用戶級或工作區(qū)級路徑,用於自定義VSCode設置。 1.用戶級路徑:Windows為C:\Users\\AppData\Roaming\Code\User\settings.json,macOS為/Users//Library/ApplicationSupport/Code/User/settings.json,Linux為/home//.config/Code/User/settings.json;2.工作區(qū)級路徑:項目根目錄下的.vscode/settings

如何使用JDBC處理Java的交易? 如何使用JDBC處理Java的交易? Aug 02, 2025 pm 12:29 PM

要正確處理JDBC事務,必須先關閉自動提交模式,再執(zhí)行多個操作,最後根據結果提交或回滾;1.調用conn.setAutoCommit(false)以開始事務;2.執(zhí)行多個SQL操作,如INSERT和UPDATE;3.若所有操作成功則調用conn.commit(),若發(fā)生異常則調用conn.rollback()確保數據一致性;同時應使用try-with-resources管理資源,妥善處理異常並關閉連接,避免連接洩漏;此外建議使用連接池、設置保存點實現部分回滾,並保持事務盡可能短以提升性能。

在Java的掌握依賴注入春季和Guice 在Java的掌握依賴注入春季和Guice Aug 01, 2025 am 05:53 AM

依賴性(di)IsadesignpatternwhereObjectsReceivedenciesenciesExtern上,推廣looseSecouplingAndEaseerTestingThroughConstructor,setter,orfieldInjection.2.springfraMefringframeWorkSannotationsLikeLikeLike@component@component,@component,@service,@autowiredwithjava-service和@autowiredwithjava-ligatiredwithjava-lase-lightike

了解Java虛擬機(JVM)內部 了解Java虛擬機(JVM)內部 Aug 01, 2025 am 06:31 AM

TheJVMenablesJava’s"writeonce,runanywhere"capabilitybyexecutingbytecodethroughfourmaincomponents:1.TheClassLoaderSubsystemloads,links,andinitializes.classfilesusingbootstrap,extension,andapplicationclassloaders,ensuringsecureandlazyclassloa

如何使用Java的日曆? 如何使用Java的日曆? Aug 02, 2025 am 02:38 AM

使用java.time包中的類替代舊的Date和Calendar類;2.通過LocalDate、LocalDateTime和LocalTime獲取當前日期時間;3.使用of()方法創(chuàng)建特定日期時間;4.利用plus/minus方法不可變地增減時間;5.使用ZonedDateTime和ZoneId處理時區(qū);6.通過DateTimeFormatter格式化和解析日期字符串;7.必要時通過Instant與舊日期類型兼容;現代Java中日期處理應優(yōu)先使用java.timeAPI,它提供了清晰、不可變且線

Google Chrome無法打開本地文件 Google Chrome無法打開本地文件 Aug 01, 2025 am 05:24 AM

ChromecanopenlocalfileslikeHTMLandPDFsbyusing"Openfile"ordraggingthemintothebrowser;ensuretheaddressstartswithfile:///;2.SecurityrestrictionsblockAJAX,localStorage,andcross-folderaccessonfile://;usealocalserverlikepython-mhttp.server8000tor

了解網絡端口和防火牆 了解網絡端口和防火牆 Aug 01, 2025 am 06:40 AM

NetworkPortSandFireWallsworkTogetHertoEnableCommunication whereSeringSecurity.1.NetWorkPortSareVirtualendPointSnumbered0-655 35,with-Well-with-Newonportslike80(HTTP),443(https),22(SSH)和25(smtp)sindiessingspefificservices.2.portsoperateervertcp(可靠,c

比較Java框架:Spring Boot vs Quarkus vs Micronaut 比較Java框架:Spring Boot vs Quarkus vs Micronaut Aug 04, 2025 pm 12:48 PM

前形式攝取,quarkusandmicronautleaddueTocile timeProcessingandGraalvSupport,withquarkusoftenpernperforminglightbetterine nosserless notelless centarios.2。

See all articles