質問するログイン新規登録

Q&A

解決済

2回答

2288閲覧

深い階層にあるものをJacksonのObjectMapperを使ってマッピングしたい

syoshinsya-

総合スコア48

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2023/06/23 17:05

0

0

実現したいこと

jsonの深い階層にあるデータを掘り起こしてマッピングしたいです。

前提

このようなJsonファイルがあるとします。

json

1{ 2 "name": "tarou", 3 "data": { 4 "age": 26 5 } 6}

これをマッピングする際に以下のようなクラスでマッピングを行いたいと思っています。
この中にDataクラスを入れればいいというのは無しでお願いします。
→データの中の"age"だけを取り出したいです。

java

1import lombok.Getter; 2import lombok.Setter; 3import lombok.ToString; 4 5@Getter 6@Setter 7@ToString 8public class Json { 9 private String name; 10 private int age; 11}

発生している問題・エラーメッセージ

この場合、Json内のdataをマッピングするためのプロパティがないというエラーが出ます。

Terminal

1com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "data" (class jam.genshin.testData), not marked as ignorable (2 known properties: "name", "age"]) 2 at [Source: (String)"{"name": "tarou","data": {"age": 26}}"; line: 1, column: 27] (through reference chain: jam.genshin.testData["data"])

該当のソースコード

java

1public class App 2{ 3 public static void main( String[] args ) 4 { 5 String json = "{\"name\": \"tarou\",\"data\": {\"age\": 26}}"; 6 ObjectMapper mapper = new ObjectMapper(); 7 try { 8 testData testData = mapper.readValue(json, testData.class); 9 } catch (JsonMappingException e) { 10 // TODO Auto-generated catch block 11 e.printStackTrace(); 12 } catch (JsonProcessingException e) { 13 // TODO Auto-generated catch block 14 e.printStackTrace(); 15 } 16 } 17}

試したこと

@JsonPropertyアノテーションなど試しましたが、深い階層のプロパティを直接参照することができませんでした。
(私のやり方が間違っていた可能性はあります。)

補足情報(FW/ツールのバージョンなど)

Mavenプロジェクトです

xml

1<?xml version="1.0" encoding="UTF-8"?> 2 3<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>test.test</groupId> 8 <artifactId>test</artifactId> 9 <version>0.1-test</version> 10 11 <name>test</name> 12 13 <properties> 14 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 15 <maven.compiler.source>1.7</maven.compiler.source> 16 <maven.compiler.target>1.7</maven.compiler.target> 17 </properties> 18 19 <dependencies> 20 <dependency> 21 <groupId>junit</groupId> 22 <artifactId>junit</artifactId> 23 <version>4.11</version> 24 <scope>test</scope> 25 </dependency> 26 27 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core --> 28 <dependency> 29 <groupId>com.fasterxml.jackson.core</groupId> 30 <artifactId>jackson-core</artifactId> 31 <version>2.15.2</version> 32 </dependency> 33 <dependency> 34 <groupId>com.fasterxml.jackson.core</groupId> 35 <artifactId>jackson-annotations</artifactId> 36 <version>2.15.2</version> 37 </dependency> 38 <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> 39 <dependency> 40 <groupId>com.fasterxml.jackson.core</groupId> 41 <artifactId>jackson-databind</artifactId> 42 <version>2.15.2</version> 43 </dependency> 44 45 <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --> 46 <dependency> 47 <groupId>org.projectlombok</groupId> 48 <artifactId>lombok</artifactId> 49 <version>1.18.28</version> 50 <scope>provided</scope> 51 </dependency> 52 53 54 55 <!-- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp --> 56 <dependency> 57 <groupId>com.squareup.okhttp3</groupId> 58 <artifactId>okhttp</artifactId> 59 <version>4.11.0</version> 60 </dependency> 61 </dependencies> 62 63 <build> 64 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> 65 <plugins> 66 <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle --> 67 <plugin> 68 <artifactId>maven-clean-plugin</artifactId> 69 <version>3.1.0</version> 70 </plugin> 71 <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> 72 <plugin> 73 <artifactId>maven-resources-plugin</artifactId> 74 <version>3.0.2</version> 75 </plugin> 76 <plugin> 77 <artifactId>maven-compiler-plugin</artifactId> 78 <version>3.8.0</version> 79 </plugin> 80 <plugin> 81 <artifactId>maven-surefire-plugin</artifactId> 82 <version>2.22.1</version> 83 </plugin> 84 <plugin> 85 <artifactId>maven-jar-plugin</artifactId> 86 <version>3.0.2</version> 87 </plugin> 88 <plugin> 89 <artifactId>maven-install-plugin</artifactId> 90 <version>2.5.2</version> 91 </plugin> 92 <plugin> 93 <artifactId>maven-deploy-plugin</artifactId> 94 <version>2.8.2</version> 95 </plugin> 96 <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle --> 97 <plugin> 98 <artifactId>maven-site-plugin</artifactId> 99 <version>3.7.1</version> 100 </plugin> 101 <plugin> 102 <artifactId>maven-project-info-reports-plugin</artifactId> 103 <version>3.0.0</version> 104 </plugin> 105 </plugins> 106 </pluginManagement> 107 </build> 108</project> 109

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

guest

回答2

0

ベストアンサー

Data クラスを作りたく無いなら、 Json クラスに

java

1 void setData(Json data) { 2 age = data.age; 3 }

と入れてはどうでしょう。
(※試していません。)


試しました。

java

1import com.fasterxml.jackson.core.JsonProcessingException; 2import com.fasterxml.jackson.databind.ObjectMapper; 3 4public class App { 5 public static void main( String[] args) { 6 String json = "{\"name\": \"tarou\",\"data\": {\"age\": 26}}"; 7 ObjectMapper mapper = new ObjectMapper(); 8 try { 9 System.out.println("" + mapper.readValue(json, TestData.class)); 10 } catch(JsonProcessingException e) { 11 e.printStackTrace(); 12 } 13 } 14} 15 16class TestData { 17 private String name; 18 private int age; 19 20 void setName(String name) { this.name = name; } 21 void setAge(int age) { this.age = age; } 22 void setData(TestData data) { age = data.age; } 23 24 @Override 25 public String toString() { 26 return "name=" + name + ", age=" + age; 27 } 28}

実行結果

name=tarou, age=26

投稿2023/06/23 19:03

編集2023/06/23 19:35
jimbe

総合スコア13482

syoshinsya-

2023/06/23 23:54

なるほど!その発想はありませんでした。 実行確認までしていただいてありがとうございます。
jimbe

2023/06/24 17:36 編集

>深い階層のプロパティを直接参照 ではないので、一つ下ならまだしも三つ四つとなると面倒になるでしょうね。 XML なら DOM から生成や XSLT で変換や色々と思いますが、 json / jackson / ObjectMapper は面倒(≒自由)なことは置いておいて兎に角簡単にオブジェクトをテキストと変換出来ることが売りと思いますので、無理矢理やるよりは GPT4 の回答のように捨てクラスでやっちゃった方が返って分かり易い?かも知れません。
guest

0

この回答はGPT-4による自動生成回答です

maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

### 解決方法 `@JsonCreator`と`@JsonProperty`アノテーションを使用して、コンストラクタを作成し、深い階層のプロパティを直接参照することができます。 ```java import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Getter; import lombok.Setter; import lombok.ToString; @Getter @Setter @ToString public class Json { private String name; private int age; @JsonCreator public Json(@JsonProperty("name") String name, @JsonProperty("data") Data data) { this.name = name; this.age = data.getAge(); } private static class Data { private int age; @JsonCreator public Data(@JsonProperty("age") int age) { this.age = age; } public int getAge() { return age; } } }

この方法では、Jsonクラスのコンストラクタがnamedataを受け取り、Dataクラスのインスタンスを作成してageを取得します。これにより、Jsonクラスのageプロパティに直接dataオブジェクトのageプロパティを設定することができます。

投稿2023/06/23 17:05

teratail-ai

Powered by GPT-4

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問