Jackson|booleanタイプisAメンバーのシリアル化問題


質問する


Javaプロジェクトのbooleanタイプという名前のisUpのオブジェクトメンバーがJacksonライブラリを介してJSON文字列にシリアル化されると、フィールド名がupに変更されます.シリアルJSON文字列を使用している方は固定名isUpを使用しており、相対コードを変更できないのが問題です.
@Test
void test() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    Message message = new Message(true);
    String serialized = mapper.writeValueAsString(message);
    System.out.println("serialized = " + serialized);
}

@Getter
static class Message {
    private final boolean isUp;

    public Message(boolean isUp) {
        this.isUp = isUp;
    }
}
serialized = {"up":true}

仮定


JacksonライブラリObjectMapperがオブジェクトをJSON文字列にシリアル化すると、オブジェクトのGetter名が表示され、フィールド名が決定される.
(※実は最初からそう設定しているわけではありません.文章がスムーズになるように仮定しておきます.)

検証#ケンショウ#


isUp()


まず、問題が発生したGetter名はisUp()です.Lombok@Getter宣言を使用するか、GetterをisUp()として直接定義します.上記の問題に示すように、シリアルフィールド名はupです.

getIsUp()


これは一般的なgetterネーミング法ではありませんが、このように定義すると、フィールド名はisUpにシリアル化されます.
@Test
void test() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    Message message = new Message(true);
    String serialized = mapper.writeValueAsString(message);
    System.out.println("serialized = " + serialized);
}

static class Message {
    private final boolean isUp;

    public Message(boolean isUp) {
        this.isUp = isUp;
    }
	
		public boolean getIsUp() {
				return isUp;
		}
}
serialized = {"isUp":true}

解決策


ObjectMapper.setVisibility()


第1の解決策は、JacksonライブラリObjectMappersetVisibility()を使用して設定される.下図に示すようにsetVisibility設定を使用すると、オブジェクトフィールド名がGetterなしでシリアルに保たれます.
@Test
void test() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    Message message = new Message(true);
    mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
    String serialized = mapper.writeValueAsString(message);
    System.out.println("serialized = " + serialized);
}

static class Message {
    private final boolean isUp;

    public Message(boolean isUp) {
        this.isUp = isUp;
    }
}
serialized = {"isUp":true}

getIsUp()


第2の解決策はGetter(getIsUp())を直接定義することであり、これは上述したように共通の名前ではない.最初の解決策はもっと良いです

n/a.結論


私の場合、SimpMessagingTemplate.convertAndSend()メソッドを使用してStompプロトコルのPublisherコードを記述します.この場合、ObjectMapperは、setVisibility()を直接処理するのではなく、ライブラリ内で変換するために使用できません.したがって、2番目のソリューション値オブジェクトを定義する際には、Lombokの@Getter宣言を削除し、getIsUp()などのGetterを直接定義することで問題を解決します.