エキサイト株式会社メディア事業部エンジニアの佐々木です。JVMでJSONを扱うときのライブラリであるJacksonのフィールド名の規則を定義します。
環境
Javaバージョン
$ java --version openjdk 17.0.1 2021-10-19 OpenJDK Runtime Environment (build 17.0.1+12-39) OpenJDK 64-Bit Server VM (build 17.0.1+12-39, mixed mode, sharing)
Gradleバージョン
$ ./gradlew --version ------------------------------------------------------------ Gradle 7.6 ------------------------------------------------------------ Build time: 2022-11-25 13:35:10 UTC Revision: daece9dbc5b79370cc8e4fd6fe4b2cd400e150a8 Kotlin: 1.7.10 Groovy: 3.0.13 Ant: Apache Ant(TM) version 1.10.11 compiled on July 10 2021 JVM: 17.0.1 (Oracle Corporation 17.0.1+12-39) OS: Mac OS X 12.5 aarch64
Gradle依存関係
dependencies { compileOnly 'org.projectlombok:lombok:1.18.24' annotationProcessor 'org.projectlombok:lombok:1.18.24' implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.2' }
UpperCamelCase のときのJacksonの設定
JacksonはデフォルトでLower Camel Case
を使用します。なので、JSONのフィールド名が先頭大文字だと、エラーになります。
下記コードは先頭大文字のキャメルケースなので、実行時にエラーとなります。
public class JacksonNamingRuleTest { private static String upperCamelCaseText = """ [ { "IndexId": 0 ,"FirstName": "index1" }, { "IndexId": 1 ,"FirstName": "index2" } ] """; public static void main(String[] args) throws IOException { ObjectMapper objectMapper = new ObjectMapper(); List<UpperCamelCaseForm> upperCamelCaseForms = objectMapper.readValue(upperCamelCaseText, new TypeReference<>() { }); log.info("upper camel case: {}", upperCamelCaseForms); } @Data static class UpperCamelCaseForm { private int IndexId; private String FirstName; } } 実行時... ==== Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "IndexId" (class com.example.demo.JacksonNamingRuleTest$UpperCamelCaseForm), not marked as ignorable (2 known properties: "firstName", "indexId"])
これを修正するには、データクラスにアノテーションをつけるだけになります。
@Data @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) // <- これを追加する static class UpperCamelCaseForm { private int IndexId; private String FirstName; }
これで正常に動作します。
SnakeCase のときのJacksonの設定
SnakeCaseのときも、データクラスにアノテーションをつけるだけになります。
@Data @JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class) // <- これを追加する static class SnakeCaseForm { private int IndexId; private String FirstName; }
キャメルケースやスネークケースが混在する場合
既存のAPI等であるのが、キャメルケースやスネークケースが混在する場合があります。その場合は、ベースをどちらかに決めて、@JsonProperty
アノテーションを使用し、回避していきます。
下記は、ベースをアッパーキャメルケースにして
にして、FirstName
のプロパティがスネークケースの場合の例になります。
@Data @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) static class SnakeCaseForm { private int indexId; @JsonProperty("first_name") // <- ここにスネークケースのプロパティ名を記述 private String FirstName; }
まとめ
アノテーションひとつで実際のコードの変更は行わずに挙動を変えることができるのは便利なです。しかし、実行してみるまでわからないや覚えることが多いなどの課題もありますが、やはり便利です。 面倒な処理はアノテーションに閉じ込めて重要なビジネスロジックに専念していけるようにしたいです。
最後に
エキサイトではフロントエンジニア、バックエンドエンジニア、アプリエンジニアを随時募集しております。長期インターンも歓迎していますので、興味があれば連絡いただければと思います。
カジュアル面談はこちらになります! meety.net
募集職種一覧はこちらになります!(カジュアルからもOK) www.wantedly.com