Преобразование строки в JSON -> в объект

Привет, всем.
Возможно, тема уже подымалась.

Я попытался протестировать API, который отдаёт ответ JSON с Content-Type: text/html; charset=UTF-8. В коде пытался преобразовать ответ в объект путём:

MyModel model = response.as(MyModel.class);

У меня появилась ошибка:

java.lang.IllegalStateException: Cannot parse object because no supported Content-Type was specified in response. Content-Type was 'text/html; charset=UTF-8'.

Решил преобразовывать в объект другим путём:

String s = response.asString();
JsonPath jsonPath = JsonPath.from(s);
MyModel testMyModel = jsonPath.getObject("$", MyModel.class);

но получил следующую ошибку:

java.lang.IllegalStateException: Cannot deserialize object because no JSON deserializer found in classpath. Please put either Jackson (Databind) or Gson in the classpath.

Для решения этой проблемы воспользовался добавлением в pom.xml библиотеки:

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>

но и тут поджидала очередная ошибка:

java.lang.NoClassDefFoundError: com/fasterxml/jackson/annotation/JsonMerge

Чтобы её пофиксить, нужно понизить версию библитеки jackson-databind до 2.8.x (https://www.mkyong.com/gradle/java-lang-noclassdeffounderror-comfasterxmljacksonannotationjsonmerge/). Попробовав у меня всё равно воспроизвелась та же ошибка. Тогда понизил версию библиотеки до 2.7.9.5, перезапустил и всё заработало!

Надеюсь, кому-нибудь будет полезно.

1 лайк

response.body() десериализуйте

и snakeyaml лучше чем jackson (YMMV - мнение мое личное)

то есть я имел в виду скорее
com.alibaba.fastjson
и org.json.json

1 лайк

Попробовал

MyModel testMyModel = response.body().as(MyModel.class);

и получил ошибку:

java.lang.IllegalStateException: Cannot parse object because no supported Content-Type was specified in response. Content-Type was 'text/html; charset=UTF-8'.

@blink2004 более древние и менее мажорные интсрументы чем джексон рекоммендуют less strong-typed approach:

        JSONObject obj = new JSONObject(json);
        String  bar = obj.getJSONObject("{foo:bar}").getString("foo");

ну и т.д.

https://www.testingexcellence.com/how-to-parse-json-in-java/

OK. Тогда это уже другие библиотеки и другая история :slight_smile:

@blink2004 вы сов правы но восток ^W лоу левел форматы штука тонкая и это помоему оправдывает выбор интсрумента - я по крайне й мере один случай знаю где jackson не могет… и что - писать в oss jiira у меня времени не хватает -

Самый простой вариант - Gson

Gson gson = new Gson();
MyModel model = gson.fromJson(json, MyModel.class);

Где json - JSON строка

Здесь можно наити примеры JSON to object и JSON to array/list

Кроме того, я лично если проект позволяет (и чаще всего так и есть) сразу работаю с requests/responses как с обьектами. RESTEasy proxy framework - супер удобно. Если того требует проект всегда можно опуститься на “HTTP” уровень и работать непосредсвенно с headers/response code/body

Здесь масса примеров

Правда на английском

1 лайк

Если в классе будет поле типа Map<String, Serializable> params, то может и не распарсится :slightly_smiling_face:

О да, в любом варианте есть куча кейсов когда нужно исполнить ритуальный танец с бубном :grinning: