LoginSignup
1
2

More than 5 years have passed since last update.

lombokとJSONICでJSONHintアノテーションが動作しない場合の対処

Posted at

JSONICとlombok併用時に@JSONHintアノテーションが上手く動作しなかったので、その回避策に関するメモ。

使用バージョン

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.20</version>
</dependency>

<dependency>
    <groupId>net.arnx</groupId>
    <artifactId>jsonic</artifactId>
    <version>1.3.10</version>
</dependency>

現象と回避策

サンプルとして以下の形式の日付文字列を含むJSONをパースしたい、とする。

String json = "{dateTime: \"2018-03-29T11:22:33.123+09:00\"}";
SampleData s = JSON.decode(json, SampleData.class);

lombokを使用するクラスはこんな感じ。

import java.time.LocalDateTime;

import lombok.Data;
import net.arnx.jsonic.JSONHint;

@Data
public class SampleData {
    @JSONHint(format="yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ")
    private LocalDateTime dateTime;
}

これは以下のような例外となり@JSONHintアノテーションが有効になっていないことがわかる。

Exception in thread "main" net.arnx.jsonic.JSONException: {dateTime=2018-03-29T11:22:33.123+09:00} は class asdf.asdfasd.SampleData に変換できませんでした: $.dateTime
    at net.arnx.jsonic.JSON$Context.convertInternal(JSON.java:1775)
    at net.arnx.jsonic.JSON.parse(JSON.java:1155)
    at net.arnx.jsonic.JSON.parse(JSON.java:1130)
    at net.arnx.jsonic.JSON.decode(JSON.java:665)
    at asdf.asdfasd.App.main(App.java:15)
Caused by: java.time.format.DateTimeParseException: Text '2018-03-29T11:22:33.123+09:00' could not be parsed, unparsed text found at index 23
    at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1952)
    at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)

これの原因だが、https://ja.osdn.net/projects/jsonic/ticket/35184 にJSONICはgetter/setterがある場合はそちらのアノテーションを優先する、とある。lombokはgetter/setterを自動生成するが、そちらには@JSONHintが無いので、このような状況になる。

というわけで回避策として、対象のプロパティについては自前でgetter/setterを定義してしまうことにした。

@Data
public class SampleData {
    /* このプロパティのgetter/setterは不要なので自動生成を抑制 */
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private LocalDateTime d;

    public LocalDateTime getDateTime() {
        return d;
    }

    @JSONHint(format="yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ")
    public void setDateTime(LocalDateTime dateTime) {
        this.d = dateTime;
    }
}

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2