Gsonを使ってJavaをJsonに変換してみました

Gsonとは



JavaオブジェクトをJsonに変換するために使用できるJavaライブラリです。

Jsonの文字列をJavaオブジェクトに変換することもできます。

英語ですが、使い方の詳細は下記に載っています。



github.com





実際にサンプルコードを作成して動作確認をしてみました。






JavaからJsonへ変換



Weather.java クラスをJsonに変換します。




package gson;
import lombok.*;
import java.time.LocalDateTime;

@Data
@ToString
@EqualsAndHashCode
@AllArgsConstructor
public class Weather {

private Long id;
private String area;
private String datelabel;
private String telop;
private Integer min_temperature;
private Float min_fahrenheit;
private Integer max_temperature;
private Float max_fahrenheit;
private String comment;
private LocalDateTime yyyymmdd;
}







JavaからJsonへ変換する場合はtoJson()を使います。

引数にJavaオブジェクトを指定すると、Json形式の文字列にしてくれます。




Gson gson = new Gson();
String json = gson.toJson(weather);







Gson()を使った場合、項目の値が null の項目は無視されてJsonが作成されますが、
null として表示させたい場合はGsonBuilder()を使います。

下記では weather1 の項目「area」を null にしています。




Weather weather1 = new Weather(1L, null, "今日", "晴れ", 2, 35.6f, 11, 51.8f, "北風が強いので洗濯物に注意するべし", LocalDateTime.of(2018, 1, 6, 5, 0, 0));
Weather weather2 = new Weather(1L, "東京", "明日", "曇り", 1, 33.8f, 5, 41f, "夕方雨が降るかもしれないので折畳み傘を持つべし", LocalDateTime.of(2018, 1, 7, 5, 0, 0));
Weather weather3 = new Weather(1L, "東京", "明後日", "雨", 3, 37.4f, 6, 42.8f, "夜になると雨が強くなるので早く帰るべし", LocalDateTime.of(2018, 1, 8, 5, 0, 0));

List<Weather> weatherList = new ArrayList<>();
weatherList.add(weather1);
weatherList.add(weather2);
weatherList.add(weather3);

// Nullの項目は無視される
Gson gson = new Gson();
System.out.println("JsonからJavaへ変換(Null無視): " + gson.toJson(weatherList));

// Nullの項目も出力する
Gson gson2 = new GsonBuilder().serializeNulls().create();
System.out.println("JsonからJavaへ変換(Nullあり): " + gson2.toJson(weatherList));





【実行結果】




JsonからJavaへ変換(Null無視): [{"id":1,"datelabel":"今日","telop":"晴れ","min_temperature":2,"min_fahrenheit":35.6,"max_temperature":11,"max_fahrenheit":51.8,"comment":"北風が強いので洗濯物に注意するべし","yyyymmdd":{"date":{"year":2018,"month":1,"day":6},"time":{"hour":5,"minute":0,"second":0,"nano":0}}},{"id":1,"area":"東京","datelabel":"明日","telop":"曇り","min_temperature":1,"min_fahrenheit":33.8,"max_temperature":5,"max_fahrenheit":41.0,"comment":"夕方雨が降るかもしれないので折畳み傘を持つべし","yyyymmdd":{"date":{"year":2018,"month":1,"day":7},"time":{"hour":5,"minute":0,"second":0,"nano":0}}},{"id":1,"area":"東京","datelabel":"明後日","telop":"雨","min_temperature":3,"min_fahrenheit":37.4,"max_temperature":6,"max_fahrenheit":42.8,"comment":"夜になると雨が強くなるので早く帰るべし","yyyymmdd":{"date":{"year":2018,"month":1,"day":8},"time":{"hour":5,"minute":0,"second":0,"nano":0}}}]
JsonからJavaへ変換(Nullあり): [{"id":1,"area":null,"datelabel":"今日","telop":"晴れ","min_temperature":2,"min_fahrenheit":35.6,"max_temperature":11,"max_fahrenheit":51.8,"comment":"北風が強いので洗濯物に注意するべし","yyyymmdd":{"date":{"year":2018,"month":1,"day":6},"time":{"hour":5,"minute":0,"second":0,"nano":0}}},{"id":1,"area":"東京","datelabel":"明日","telop":"曇り","min_temperature":1,"min_fahrenheit":33.8,"max_temperature":5,"max_fahrenheit":41.0,"comment":"夕方雨が降るかもしれないので折畳み傘を持つべし","yyyymmdd":{"date":{"year":2018,"month":1,"day":7},"time":{"hour":5,"minute":0,"second":0,"nano":0}}},{"id":1,"area":"東京","datelabel":"明後日","telop":"雨","min_temperature":3,"min_fahrenheit":37.4,"max_temperature":6,"max_fahrenheit":42.8,"comment":"夜になると雨が強くなるので早く帰るべし","yyyymmdd":{"date":{"year":2018,"month":1,"day":8},"time":{"hour":5,"minute":0,"second":0,"nano":0}}}]





整形した実行結果です。(null表示あり版)




[
{
"area": null,
"comment": "北風が強いので洗濯物に注意するべし",
"datelabel": "今日",
"id": 1,
"max_fahrenheit": 51.8,
"max_temperature": 11,
"min_fahrenheit": 35.6,
"min_temperature": 2,
"telop": "晴れ",
"yyyymmdd": {
"date": {
"day": 6,
"month": 1,
"year": 2018
},
"time": {
"hour": 5,
"minute": 0,
"nano": 0,
"second": 0
}
}
},
{
"area": "東京",
"comment": "夕方雨が降るかもしれないので折畳み傘を持つべし",
"datelabel": "明日",
"id": 1,
"max_fahrenheit": 41.0,
"max_temperature": 5,
"min_fahrenheit": 33.8,
"min_temperature": 1,
"telop": "曇り",
"yyyymmdd": {
"date": {
"day": 7,
"month": 1,
"year": 2018
},
"time": {
"hour": 5,
"minute": 0,
"nano": 0,
"second": 0
}
}
},
{
"area": "東京",
"comment": "",
"datelabel": "明後日",
"id": 1,
"max_fahrenheit": 42.8,
"max_temperature": 6,
"min_fahrenheit": 37.4,
"min_temperature": 3,
"telop": "",
"yyyymmdd": {
"date": {
"day": 8,
"month": 1,
"year": 2018
},
"time": {
"hour": 5,
"minute": 0,
"nano": 0,
"second": 0
}
}
}
]






JsonからJavaへ変換



fromJson()で引数にJsonの文字列を渡すと、Javaオブジェクトに変換してくれます。
前手順で作成した Jsonデータを、Weatherクラスに変換します。




Weather weather = gson.fromJson(gson.toJson(weatherList.get(0)), Weather.class);
System.out.println(weather.toString());





【実行結果】




Weather(id=1, area=null, datelabel=今日, telop=晴れ, min_temperature=2, min_fahrenheit=35.6, max_temperature=11, max_fahrenheit=51.8, comment=北風が強いので洗濯物に注意するべし, yyyymmdd=2018-01-06T05:00)






項目名をキャメルに変換する



JavaオブジェクトからJsonに変換するとき、何も指定しないとJavaオブジェクトの変数名がそのままJsonの項目名になりますが、
GsonBuilder()を使うことでキャメルケースやスネークケースに変換することができます。



    WeatherReportGirl weatherReportGirl = new WeatherReportGirl("曇後", "晴子", 23, LocalTime.of(5, 0, 0));

Gson gson1 = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
Gson gson2 = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE_WITH_SPACES).create();
Gson gson3 = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
Gson gson4 = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES).create();

System.out.println("キャメルケース : " + gson1.toJson(weatherReportGirl));
System.out.println("キャメルケース(区切りがスペース): " + gson2.toJson(weatherReportGirl));
System.out.println("スネークケース : " + gson3.toJson(weatherReportGirl));
System.out.println("スネークケース(区切りがダッシュ): " + gson4.toJson(weatherReportGirl));





【実行結果】




キャメルケース : {"LastName":"曇後","FirstName":"晴子","Age":23,"StartingTime":{"Hour":5,"Minute":0,"Second":0,"Nano":0}}
キャメルケース(区切りがスペース): {"Last Name":"曇後","First Name":"晴子","Age":23,"Starting Time":{"Hour":5,"Minute":0,"Second":0,"Nano":0}}
スネークケース : {"last_name":"曇後","first_name":"晴子","age":23,"starting_time":{"hour":5,"minute":0,"second":0,"nano":0}}
スネークケース(区切りがダッシュ): {"last-name":"曇後","first-name":"晴子","age":23,"starting-time":{"hour":5,"minute":0,"second":0,"nano":0}}







Javaオブジェクトに@SerializedNameで項目名を指定しておくと、GsonBuilder()を使っても変換されません。




package gson;

import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.time.LocalTime;

@Data
@ToString
@EqualsAndHashCode
@AllArgsConstructor
public class WeatherReportGirl {
@SerializedName("lastName")
private String lastName;
private String firstName;
private int age;
private LocalTime startingTime;
}





【実行結果】




キャメルケース : {"lastName":"曇後","FirstName":"晴子","Age":23,"StartingTime":{"Hour":5,"Minute":0,"Second":0,"Nano":0}}
キャメルケース(区切りがスペース): {"lastName":"曇後","First Name":"晴子","Age":23,"Starting Time":{"Hour":5,"Minute":0,"Second":0,"Nano":0}}
スネークケース : {"lastName":"曇後","first_name":"晴子","age":23,"starting_time":{"hour":5,"minute":0,"second":0,"nano":0}}
スネークケース(区切りがダッシュ): {"lastName":"曇後","first-name":"晴子","age":23,"starting-time":{"hour":5,"minute":0,"second":0,"nano":0}}






使ってみた感想



JavaオブジェクトをそのままJsonに変換できるので、とても使いやすかったです。

ここで紹介した使い方以外にも、serializerをimplementsして変換先となるJavaオブジェクトを変更したりできるようでしたが、
変更が必要な場合はJavaオブジェクト自体を別で作成したほうが良いのではないかと思ったので、
必要になる場面がよくわかりませんでした。





簡単に変換できるJavaのライブラリがあることを初めて知ったので、
活用できそうな場があったら業務でも使ってみたいと思います。





今回作成したコードはgithubにあげてあります。



github.com