Остановить чтение Джексоном чисел как строки

Джексон читает входные числа как строки. В качестве примера ниже студенческий класс читает имя 4567 как строку.

пример: ввод

{
name: 4567
...
}

Java-класс

Class Student {

String name;
...
}

Джексон анализирует текст JSON и сопоставляет числовое значение со строковым полем, и я не хочу, чтобы преобразование типа, т.е. чтобы число было преобразовано в строку. В этом сценарии Джексон преобразует значение из int (4567) в String("4567"). Как это поведение может измениться, чтобы генерировать исключение, если другой тип не работает?


person era    schedule 28.03.2019    source источник
comment
Вы хотите проверить, вводит ли пользователь имя, содержащее только буквы?   -  person J. Doe    schedule 28.03.2019
comment
@OamarKanji В области вычислительной техники Джексон представляет собой высокопроизводительный процессор JSON для Java. Его разработчики превозносят сочетание быстрых, правильных, легких и эргономичных атрибутов библиотеки. -Википедия   -  person J. Doe    schedule 28.03.2019
comment
@OamarKanji Jackson — известная библиотека JSON для Java: github.com/FasterXML/jackson   -  person Andreas    schedule 28.03.2019
comment
@ MS90 Кажется, вы неправильно поняли вопрос. Джексон анализирует текст JSON и сопоставляет числовое значение со строковым полем, а OP не хочет, чтобы преобразование типа, т. е. число, было преобразовано в строку. По сути, OP хочет рассматривать текст JSON как недействительный.   -  person Andreas    schedule 28.03.2019
comment
Поскольку тип данных в вашем классе StudentString, вы можете изменить его на int.   -  person LunaticJape    schedule 28.03.2019
comment
@MS90 OP хочет, чтобы name было String, и хочет убедиться, что при анализе/десериализации JSON значение представляет собой строку JSON, например. "4567", а не номер JSON, например. 4567. Джексон преобразует значение из int в String, что является хорошей полезной библиотекой, но OP хочет, чтобы она не работала. --- если он хочет десерлировать контент, у него не возникнет никаких проблем проблема в том, что он не терпит неудачу. OP хочет провалить его. ОП хочет, чтобы это было проблемой.   -  person Andreas    schedule 28.03.2019
comment
@Andreas Андреас Но почему он вообще сериализовал это как int? Логики в этом коде нет вообще. Вместо того, чтобы исправить то, что изначально вызвало весь этот беспорядок, мы добавим ему больше проблем через некоторое время. Его единственная проблема и проблема - это код в сериализации, в первую очередь.   -  person MS90    schedule 28.03.2019
comment
@ MS90 Проверьте свои предположения. OP не сериализовал его как int. OP анализирует JSON неизвестного происхождения и требует строгого анализа, поэтому он не работает, если тип значения JSON неверен. Почему вы решили, что текст JSON был создан Джексоном? Перефразируя, вопрос просто говорит: у меня есть этот JSON для анализа в этот объект, и я хочу, чтобы он не анализировался, поскольку тип неправильный (Как это поведение может измениться, чтобы вызвать исключение< /b> ?).   -  person Andreas    schedule 28.03.2019
comment
Если он разбирает JSON неизвестного происхождения, то он наверняка должен следовать логике кода, который собирается разобрать. Есть причина, по которой создатели такого JSON сериализовали это поле как int? @Андреас   -  person MS90    schedule 28.03.2019
comment
@ MS90 MS90 Что, если OP является автором схемы JSON, а какой-то другой идиот неправильно создал JSON? Или OP просто реализовал код, соответствующий общей схеме, и сделал это правильно, то есть это должна быть строка (в конце концов, это значение name). Вы должны жить в маленьком мире, если не можете себе представить, что совместное использование данных может пойти не так, и что вы хотите/нуждается строгий синтаксический анализ для предотвращения случайного неправильного толкования данных. JSON — это не только формат хранения, в котором вы читаете/записываете свои собственные данные, это также формат обмена для обмена данными между разрозненными системами (например, веб-службой REST).   -  person Andreas    schedule 28.03.2019
comment
Согласен, но маловероятно, что он взял бы какой-нибудь JSON для своего проекта у какого-то идиота и теперь хочет просветить мир своей логикой, как его десериализовать. Во всяком случае, даже имя имени поля подразумевает, что оно должно быть типа String, не говоря уже обо всех других причинах, по которым его подход и ваше преследование были бы неправильными со всем этим. Я живу в очень маленьком мире, нет смысла мне об этом говорить, но он должен знать, что делает, а он, видимо, не знает. Если бы кто-то 10 лет назад сказал мне, что в вашем коде следует следовать логике, я бы сэкономил себе дни и дни на ошибки.   -  person MS90    schedule 28.03.2019
comment
подходы и реализации. @Андреас У него есть шанс прямо здесь и сейчас. Не поощряйте его идти другим путем.   -  person MS90    schedule 28.03.2019
comment
Спасибо @Andreas за все разъяснения. Это подробно из необходимости. Приведенная выше схема JSON является частью REST API, предоставляемой клиенту. В API (Swagger) параметр name помечен как String. Но теперь клиент отправляет за него int и просит с нашей стороны (из API) потерпеть неудачу.   -  person era    schedule 29.03.2019
comment
Аналогичная ошибка есть на GitHub, где вы можете найти решение с десериализатором по умолчанию.   -  person Michał Ziober    schedule 29.03.2019


Ответы (1)


Пользовательский десериализатор, зарегистрированный для java.lang.String, определенно должен работать и позволит вам предотвратить преобразование. Десериализаторы будут напрямую видеть контент через JsonParser, чтобы они могли определить базовый тип токена.

Это поможет вам:

public class ForceStringDeserializer extends JsonDeserializer<String> {

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        if (jsonParser.getCurrentToken() == JsonToken.VALUE_NUMBER_INT) {
            throw deserializationContext.wrongTokenException(jsonParser, JsonToken.VALUE_STRING, "Attempted to parse int to string but this is forbidden");
        }
        return jsonParser.getValueAsString();
    }
}

Дополнительную информацию можно найти здесь.

person Spara    schedule 28.03.2019
comment
@ MS90, не могли бы вы уточнить больше? Потому что я думаю, что это именно то, что нужно ОП! - person Spara; 28.03.2019
comment
Я хотел сказать, что это вообще не имеет логики в коде. Ваш ответ правильный и соответствует запросу OP, но его логика десериализации имени в int для меня вне всякого вопроса. Что произойдет, если вместо имени у него будет пример? @Спара - person MS90; 28.03.2019
comment
@ MS90 MS90 Ага, я понял, что вы имеете в виду, и вы правы. Я надеюсь, что этот ответ поможет ОП, и он знает, что делает! - person Spara; 28.03.2019
comment
@ MS90, если пользовательский ввод относится к любому другому типу, кроме String, тогда должно быть выдано исключение. пример: следующее должно завершиться ошибкой (имя: 4567, имя: 45.678, имя: правда) Проще говоря, если что-то не с двойными кавычками, это должно потерпеть неудачу - person era; 29.03.2019
comment
Если вы нашли это решение на GitHub, вы можете хотя бы добавить ссылку на него. Он содержит очень полезное обсуждение, которое может быть полезным. - person Michał Ziober; 29.03.2019