【Java】JSON-libを使ってJSON配列を生成する際に日付型(Date)を好きなフォーマットで変換する方法
おはようございます。
最近はWEBのサービス開発などでSPA(Single Page Applicatoin)が流行って?るので、
サーバーとクライアントとのデータのやり取りをJSONで行うのはよくあるケースかと思います。
サーバー側をJavaで開発している場合に、Javaオブジェクトや Bean を JSONに変換するのに、
JSON-lib というのも結構主流なやり方かと思いますが、ちょっと日付型のところでハマったので備忘的な記事を。
※JSON-lib 自体の詳しい説明(利用方法)などは省略します。
スポンサーリンク
JSON-libとは
OSDNサイトより転載
Json-libは、beans, map, collection, Java配列、XML to JSON, DynaBeansを変革するJavaライブラリです。 Douglas Crockfordによる作業をベースにしています。
Javaオブジェクトを簡単に JSON文字列に変換したり、逆に JSON文字列からオブジェクトを生成したりといったことが可能です。
昔、XMLへの相互変換ロジックを自作したことがありますが、こういう処理って実際に作ってみると結構大変だったりします。
便利な世の中ですね。
サンプル
変換するサンプルクラスを作成。
Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | packagejp.co.doraxdora.sample; importjava.io.Serializable; importjava.util.Date; /** * パーソンクラス * * @author doraxdora * */ publicclassPersonimplementsSerializable{ /** ID */ privateintid; /** 氏名 */ privateStringname; /** 年齢 */ privateintage; /** 更新日時 */ privateDate updateDate; publicPerson(){ } /** * パーソンの生成 * * @param id * @param name * @param age */ publicPerson(intid,Stringname,intage,Date updateDate){ this.id=id; this.name=name; this.age=age; this.updateDate=updateDate; } /** * @return id */ publicintgetId(){ returnid; } /** * @param id セットする id */ publicvoidsetId(intid){ this.id=id; } /** * @return name */ publicStringgetName(){ returnname; } /** * @param name セットする name */ publicvoidsetName(Stringname){ this.name=name; } /** * @return age */ publicintgetAge(){ returnage; } /** * @param age セットする age */ publicvoidsetAge(intage){ this.age=age; } /** * @return updateDate */ publicDate getUpdateDate(){ returnupdateDate; } /** * @param updateDate セットする updateDate */ publicvoidsetUpdateDate(Date updateDate){ this.updateDate=updateDate; } } |
何故か更新日時を持つパーソンクラスです。
JavaオブジェクトからJSON文字列に変換
1 2 3 4 5 6 7 8 9 10 11 | import net.sf.json.JSONObject; publicclassHelloWorld{ publicstaticvoidmain(String[]args){ Person person=newPerson(1,"サンプル 一郎",20,newDate()); JSONObject jsonObject=JSONObject.fromObject(person); System.out.println(String.valueOf(jsonObject)); } } |
こんな感じで、Dateを持つクラスをJSONに変換すると次のような文字列が生成されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | { "age":20, "id":1, "name":"サンプル 一郎", "updateDate":{ "date":23, "day":2, "hours":10, "minutes":22, "month":3, "seconds":44, "time":1555982564167, "timezoneOffset":-540, "year":119 } } |
これはこれで正しいのですが、クライアント側で日時の部分が扱いづらい。。
対応
JSON-lib には、「JsonValueProcessor」という、変換時に対象となる値に対して処理できるインターフェースが定義されているので、
実装したクラスを作成して日付型オブジェクトに対して別途変換する処理を組み込みます。
DateJsonValueProcessor.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | packagejp.co.doraxdora.sample; import java.util.Date; import net.sf.json.JsonConfig; import net.sf.json.processors.JsonValueProcessor; import java.text.SimpleDateFormat; /** * 日付型をJSON変換する際にフォーマットする * * @author doraxdora * */ publicclassDateJsonValueProcessorimplementsJsonValueProcessor{ /* (非 Javadoc) * @see net.sf.json.processors.JsonValueProcessor#processArrayValue(java.lang.Object, net.sf.json.JsonConfig) */ @Override publicObjectprocessArrayValue(Objectvalue,JsonConfig jsonConfig){ returnprocess((Date)value,jsonConfig); } /* (非 Javadoc) * @see net.sf.json.processors.JsonValueProcessor#processObjectValue(java.lang.String, java.lang.Object, net.sf.json.JsonConfig) */ @Override publicObjectprocessObjectValue(Stringkey,Objectvalue,JsonConfig jsonConfig){ returnprocess((Date)value,jsonConfig); } /** * 日付型を文字列に変換. * * @param date * @param config * @return */ privateObjectprocess(Date date,JsonConfig config){ if(date==null){ returnnull; } SimpleDateFormat formatter=newSimpleDateFormat("yyyy/MM/dd(E)"); returnformatter.format(date); } } |
JsonConfig に DateValueProcessor を設定して変換
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | importnet.sf.json.JSONObject; importnet.sf.json.JsonConfig; publicclassHelloWorld{ publicstaticvoidmain(String[]args){ Person person=newPerson(1,"サンプル 一郎",20,newDate()); JsonConfig config=newJsonConfig(); config.registerJsonValueProcessor(java.util.Date.class,newDateJsonValueProcessor()); JSONObject jsonObject=JSONObject.fromObject(person,config); System.out.println(String.valueOf(jsonObject)); } } |
という感じで、日付型だった場合の処理を設定して変換してあげると次のような文字列が生成されます。
1 2 3 4 5 6 | { "age":20, "id":1, "name":"サンプル 一郎", "updateDate":"2019/04/23(火)" } |
大分シンプルになりました。
まとめ
ちょっとした単発のプログラムネタでした。
実は以前 Python でも同様の問題にぶち当たったことがあって、
だったら Java でも同じようになんとかできるだろうと調べてみたという感じです。
何かのお役に立てれば。
ではでは。
ディスカッション
コメント一覧
まだ、コメントがありません