Форум программистов, компьютерный форум, киберфорум
Наши страницы
Java EE (J2EE)
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
1

Преобразовать ответ с JSON объектом в DTO

27.06.2017, 19:25. Просмотров 953. Ответов 22

Я использую API которое возвращает JSON объект такого вида:
JSON
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
"response": {
    "GeoObjectCollection": {
        "featureMember": [
            {
                "GeoObject": {
                    "Point": {
                        "pos": "37.611347 55.760241"
                    }
                }
            },
            {
                "GeoObject": {
                    "Point": {
                        "pos": "37.593965 55.771575"
                    }
                }
            }
        ]
    }
}
}
Я хочу конвертировать данный объект в DTO model в моем Spring Boot приложении. Как это можно сделать? Во всех, примерах, которые я находил, рассматривался самый простой объект вида, как, например, здесь:
JSON
1
2
3
4
5
6
7
{
   type: "success",
   value: {
      id: 10,
      quote: "Really loving Spring Boot, makes stand alone Spring apps easy."
   }
}
И там создали два класса DTO и на этом все. Как действовать здесь, не понятно.

Нужно создавать классы response, GeoObjectCollection, GeoObject и т.д. или есть что-то проще и правильней?

Добавлено через 1 час 51 минуту
Вообщем сделал класс:

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package ru.geo.converter.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
 
@Data
public class GeographicCoordinatesDto {
   @JsonProperty("response")
   private ResponseResult responseResult;
}
 
@Data
class ResponseResult {
   @JsonProperty("GeoObjectCollection")
   private GeoObjectCollection geoObjectCollection;
}
 
@Data
class GeoObjectCollection {
  @JsonProperty("featureMember")
  private List<FeatureMember> featureMember;
}
 
@Data
class FeatureMember {
   @JsonProperty("GeoObject")
   private GeoObject geoObject;
}
 
@Data
class GeoObject {
   @JsonProperty("Point")
   private PointItem pointItem;
}
 
@Data class PointItem {
   @JsonProperty("pos")
   private String geoCoordinates;
}
Затем пытаюсь маппить:
Java
1
2
GeographicCoordinatesDto geographicCoordinatesDto = mapper.readValue(jsonInString, GeographicCoordinatesDto.class);
System.out.println(geographicCoordinatesDto.getResponseResult());
В итоге возвращается следующее:
Java
1
ResponseResult(geoObjectCollection=GeoObjectCollection(featureMember=[FeatureMember(geoObject=GeoObject(pointItem=PointItem(geoCoordinates=37.611347 55.760241))), FeatureMember(geoObject=GeoObject(pointItem=PointItem(geoCoordinates=37.593965 55.771575)))]))
Но, стоит добавить в JSON ряд других полей, все падает. Понятно, что данный JSON содержит множество других данных, которые мне абсолютно не нужны при парсинге, не описывать же каждый из них в классах. Мне просто нужно забрать координаты.

Неужели ни у кого нет мыслей и с такой задачей не сталкивался?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.06.2017, 19:25
Ответы с готовыми решениями:

Комплексный json - ответ в spring boot используя jackson
Пишу spring mvc. Для отправки json использую view с полями id, name, phone. И...

Java, JSON и JSON Simple. Непонятка с созданием объекта JSON на сервере для отправки на фронт
Здравствуйте. Разрабатываю интернет-магазин на Java. Мне нужно на фронте...

Как на java сделать JSON запрос и ответ от какого нибудь определенного сайта. Как это все делается ?
цццц

Dto-Entity mapper
Привет. Есть дто, есть энтити, надо одно копировать в другое, ну и обратно....

Маппинг запроса в DTO
Всем привет! Столкнулся с определенными трудностями. Приложение написано на...

22
dalay_lama
79 / 79 / 50
Регистрация: 22.09.2012
Сообщений: 493
29.06.2017, 03:18 2
Neo-X2006, если вам нужны не все поля из json-а, используйте аннотацию - JsonIgnoreProperties(ignoreUnknown = true). В таком случае из json-а будут браться только те поля, которые описаны в классе.
Java
1
2
3
4
@JsonIgnoreProperties(ignoreUnknown = true)
public class YoureClass {
//somthing
}
0
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
29.06.2017, 13:46  [ТС] 3
Добавлено через 30 секунд
dalay_lama, Да, это я уже сделал, сработало.
Но остается открытым вопрос, мне на каждый объект, содержащейся в JSON, нужно создавать отдельный класс или как то иначе надо делать? Не могу понять как правильно будет.
0
xoraxax
1332 / 1276 / 376
Регистрация: 05.07.2013
Сообщений: 6,117
Завершенные тесты: 1
29.06.2017, 13:51 4
если ты собираешься работать с этими объектами, то естественно их надо делать
0
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
29.06.2017, 14:10  [ТС] 5
xoraxax, фишка в том, что мне нужно достать только "pos": "37.593965 55.771575", остальное как-бы не нужно. Может как то-можно создать DTO только на объект Point?
0
dalay_lama
79 / 79 / 50
Регистрация: 22.09.2012
Сообщений: 493
29.06.2017, 14:31 6
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
фишка в том, что мне нужно достать только "pos": "37.593965 55.771575", остальное как-бы не нужно.
Ну, а в чём проблема то?

допустим имеем json"
JSON
1
2
3
4
{
   someField: "one",
   someField2: "two"
}
Имеем классы:

Java
1
2
3
4
5
6
7
8
9
10
11
//в этом классе тебе допустим нужно только поле someField из json-а
@JsonIgnoreProperties(ignoreUnknown = true)
public class SomeClass {
   private String someField;
}
 
//в этом только someField2
@JsonIgnoreProperties(ignoreUnknown = true)
public class SomeClassTwo {
   private String someField2;
}
Десериализуем json в классы
Java
1
2
3
SomeClass someClass = mapper.readValue(jsonInString, SomeClass.class);//здесь считается только поле someField, остальные проигнарируются
 
SomeClassTwo someClassTwo = mapper.readValue(jsonInString, SomeClassTwo.class);//здесь считается только поле someField2, остальные проигнарируются
не пойму, что тебе не понятно))
0
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
29.06.2017, 15:20  [ТС] 7
dalay_lama, с простыми JSON'ами все предельно понятно, я не могу понять как быть с вложенностью объектов, как у меня, + они еще в массиве.
Так ведь то работать не будет!
Java
1
2
3
4
@JsonIgnoreProperties(ignoreUnknown = true)
public class Point{
   private String pos;
}
0
xoraxax
1332 / 1276 / 376
Регистрация: 05.07.2013
Сообщений: 6,117
Завершенные тесты: 1
29.06.2017, 15:48 8
если нужна одна единственная строка, можешь вообще регуляркой достать

Добавлено через 11 минут
ну или так objectMapper.readValue(json, ObjectNode.class).findValues("pos")
2
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
29.06.2017, 16:02  [ТС] 9
xoraxax, так там массив объектов, мне нужно из каждого доставать
0
xoraxax
1332 / 1276 / 376
Регистрация: 05.07.2013
Сообщений: 6,117
Завершенные тесты: 1
29.06.2017, 16:23 10
напиши в иде, посмотри как работает >_<
0
LeX
343 / 342 / 107
Регистрация: 30.06.2010
Сообщений: 1,338
29.06.2017, 17:31 11
Neo-X2006, попробуй, отпишешься рабочая либа или нет
1
xoraxax
1332 / 1276 / 376
Регистрация: 05.07.2013
Сообщений: 6,117
Завершенные тесты: 1
29.06.2017, 23:50 12
Цитата Сообщение от LeX Посмотреть сообщение
Neo-X2006, попробуй, отпишешься рабочая либа или нет
зачем лишние либы, если jackson все делает?

Добавлено через 15 секунд
Цитата Сообщение от LeX Посмотреть сообщение
Neo-X2006, попробуй, отпишешься рабочая либа или нет
зачем лишние либы, если jackson все делает?
0
dalay_lama
79 / 79 / 50
Регистрация: 22.09.2012
Сообщений: 493
30.06.2017, 10:45 13
Neo-X2006, всё, извини, до меня дошло в чём твоя проблема)

ну в общем-то, мне кажется у тебя здесь 3 варианта
1. Описать полную структуру json-а классом.
2. Как уже советовал xoraxax, -
Цитата Сообщение от xoraxax Посмотреть сообщение
можешь вообще регуляркой достать
.
3. Про третий способ можешь почитать здесь тык

Мне кажется самое простое и действенное, учитывая что тебе из файла нужно получить просто список "pos", написать регулярку, которая тебе будет возвращать этот список вхождений.
0
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
30.06.2017, 11:49  [ТС] 14
dalay_lama,
Цитата Сообщение от dalay_lama Посмотреть сообщение
1. Описать полную структуру json-а классом.
Как это можно делать?))) Создавать по отдельному файлу с классом на каждый объект, либо же все можно описать в одном файле? Просто хочется понять, как правильно))
0
dalay_lama
79 / 79 / 50
Регистрация: 22.09.2012
Сообщений: 493
30.06.2017, 12:33 15
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
Как это можно делать?))) Создавать по отдельному файлу с классом на каждый объект, либо же все можно описать в одном файле? Просто хочется понять, как правильно))
Ну твоя структура классов в начале топика и есть полное описание структуры json-а, у тебя там всё правильно, если ты хотел описать полную структуру. Используй JsonIgnoreProperties для того, чтобы избежать ошибок если в структуру json-а, будут добавлены поля, которые у тебя не учитываются в классе.

Если тебе не хочется на каждую фигурную скобу создавать класс, чтобы в итоге получить только свойство "pos", тогда ты должен объяснить jackson-ну, что ты хочешь найти в дереве json-а(смотри ту ссылку, что я тебе скидывал) или ты можешь не усложнять себе жизнь и просто вытянуть все "pos" регуляркой.
1
LeX
343 / 342 / 107
Регистрация: 30.06.2010
Сообщений: 1,338
30.06.2017, 12:41 16
Цитата Сообщение от xoraxax Посмотреть сообщение
зачем лишние либы, если jackson все делает?
пруф?
0
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
30.06.2017, 14:14  [ТС] 17
Сделал с помощью регулярки так:

Java
1
List<JsonNode> objectNode = mapper.readValue(json, ObjectNode.class).findValues("Point");
В ответ пришло:
Java
1
[{"pos":"37.611347 55.760241"}, {"pos":"37.593965 55.771575"}]
А как это преобразовать в DTO? Здесь принудительно передается "ObjectNode.class", свой класс я передать не могу
0
dalay_lama
79 / 79 / 50
Регистрация: 22.09.2012
Сообщений: 493
30.06.2017, 14:50 18
Цитата Сообщение от Neo-X2006 Посмотреть сообщение
Сделал с помощью регулярки так
Не об этом шла речь. Имелось ввиду вообще не использовать ObjectMapper, а просто сделать поиск как в обычной строке.
пример

но можно и так, смотри как тебе удобнее

Цитата Сообщение от Neo-X2006 Посмотреть сообщение
А как это преобразовать в DTO? Здесь принудительно передается "ObjectNode.class", свой класс я передать не могу
Ну посмотрел бы какие методы есть у класса ObjectNode, там всё довольно просто

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class PointItem {
 
   private String geoCoordinates;
 
   public void setGeoCoordinates(String geoCoordinates) {
      this.geoCoordinates = geoCoordinates;
   }
}
 
List<JsonNode> objectNode = mapper.readValue(json, ObjectNode.class).findValues("Point"); //вот ты получил ноды
List<PointItem> listResult = new ArrayList<>();
 
for (JsonNode node : objectNode) {//перебираем каждую
   List<String> values = node.findValuesAsText("pos");
   if (values != null && !values.isEmpty()) {//если в ноде есть свойство pos
      PointItem pointItem = new PointItem();//создаём класс PointItem
      pointItem.setGeoCoordinates(values.get(0));//и передаём ему значение
      listResult.add(pointItem);
   }
}
Добавлено через 7 минут
хотя я вот сейчас не понял, тебе же нужно только "pos", зачем ты ищешь свойство "Point"?

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class PointItem {
 
   private String geoCoordinates;
 
   public void setGeoCoordinates(String geoCoordinates) {
      this.geoCoordinates = geoCoordinates;
   }
}
 
List<JsonNode> objectNode = mapper.readValue(json, ObjectNode.class).findValues("pos");//мне кажется так проще
List<PointItem> listResult = new ArrayList<>();
 
for (JsonNode node : objectNode) {
      PointItem pointItem = new PointItem();
      pointItem.setGeoCoordinates(node.asText());//теперь не придётся искать вложения, просто получаем текст найденой ноды
      listResult.add(pointItem);
}
1
LeX
343 / 342 / 107
Регистрация: 30.06.2010
Сообщений: 1,338
30.06.2017, 15:00 19
зачем такие сложности то
Java
1
2
3
4
5
6
List<JsonNode> objectNode = mapper.readValue(json, ObjectNode.class).findValues("Point"); //вот ты получил ноды
List<PointItem> listResult = new ArrayList<>();
 
for (JsonNode node : objectNode) {//перебираем каждую
   listResult.add(mapper.readValue(node.traverse(), PointItem.class);
}
0
Neo-X2006
0 / 0 / 0
Регистрация: 15.03.2016
Сообщений: 135
30.06.2017, 15:12  [ТС] 20
Цитата Сообщение от LeX Посмотреть сообщение
зачем такие сложности то
Если так, то валится с ошибкой:

Java
1
2
Exception in thread "main" com.fasterxml.jackson.databind.exc.MismatchedInputException: Can not construct instance of PointItem (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('37.611347 55.760241')
 at [Source: UNKNOWN; line: -1, column: -1]
0
30.06.2017, 15:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.06.2017, 15:12

Spring Boot Entity and DTO
Добрый день, уважаемые коллеги :senor: Потратил весь день, не могу найти ни...

Возможно ли соеденить несколько одинаковых DTO ?
К примеру, Школа, есть списки классов, у них будут одинаковые DTO, примерно...

Использование одного DTO для разных таблиц
Вопрос к опытным программистам. Eсть похожие таблицы БД и есть возможность...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru