Есть ли способ десериализации {"number1": 5L, "number2": 5L} в класс, имеющий длинные поля? - PullRequest
1 голос
/ 14 апреля 2020

При десериализации JSON:

{"number1":5L,"number2":5L}

до class с полями long я получаю ошибку ниже:

JsonParseException: неожиданный символ (' L '): ожидал, что запятая разделяет записи объекта

Как это исправить?

1 Ответ

0 голосов
/ 15 апреля 2020

JSON полезная нагрузка недействительна. Номер не может быть представлен буквой L в конце. См. Таблицу ниже:

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

Приведенное выше изображение взято из json .org . Для обработки недопустимого JSON нам нужно реализовать собственный десериализатор для класса Long:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.deser.std.NumberDeserializers;

import java.io.File;
import java.io.IOException;
import java.util.StringJoiner;

public class JsonPathApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        Id id = mapper.readValue(jsonFile, Id.class);
        System.out.println(id);
    }
}

class LongJsonDeserializer extends JsonDeserializer<Long> {


    private final NumberDeserializers.LongDeserializer longDeserializer = new NumberDeserializers.LongDeserializer(Long.TYPE, 0L);

    @Override
    public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        Long value = longDeserializer.deserialize(p, ctxt);
        goToNextTokenSilently(p);
        return value;
    }

    private void goToNextTokenSilently(JsonParser p) {
        try {
            p.nextToken();
        } catch (Exception e) {
            //log if needed
        }
    }
}

class Id {

    @JsonDeserialize(using = LongJsonDeserializer.class)
    private Long number1;

    @JsonDeserialize(using = LongJsonDeserializer.class)
    private Long number2;

    // getters, setters, toString
}
...