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

377
29 июня 2017, 02:06

Я использую API которое возвращает JSON объект такого вида:

{
"response": {
    "GeoObjectCollection": {
        "featureMember": [
            {
                "GeoObject": {
                    "Point": {
                        "pos": "37.611347 55.760241"
                    }
                }
            },
            {
                "GeoObject": {
                    "Point": {
                        "pos": "37.593965 55.771575"
                    }
                }
            }
        ]
    }
}
}

Я хочу конвертировать данный объект в DTO model в моем Spring Boot приложении. Как это можно сделать? Во всех, примерах, которые я находил, рассматривался самый простой объект вида:

{
   "foo": 
   [
     {"url":"foo1", "name":"bar1"},
     {"url":"foo2", "name":"bar2"}
   ] 
}

И там создали два класса DTO и на этом все. Как действовать здесь, не понятно.

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

Update: Вообщем сделал класс:

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;
}

Затем пытаюсь маппить:

GeographicCoordinatesDto geographicCoordinatesDto = mapper.readValue(jsonInString, GeographicCoordinatesDto.class);
System.out.println(geographicCoordinatesDto.getResponseResult());

В итоге возвращается следующее:

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 содержит множество других данных, которые мне абсолютно не нужны при парсинге, не описывать же каждый из них в классах. Мне просто нужно забрать координаты.

Неужели ни у кого нет мыслей и с такой задачей не сталкивался?

Answer 1

Если вы не хотите, писать dto объекты, то можно воспользоваться каким нибудь json парсером. Например json.

<dependency>
     <groupId>org.json</groupId>
     <artifactId>json</artifactId>
     <version>2016RE0810</version>
</dependency>

Тогда данные, с его помощью, можно получить следующим образом:

String text = "{\n" +
            "\"response\": {\n" +
            "    \"GeoObjectCollection\": {\n" +
            "        \"featureMember\": [\n" +
            "            {\n" +
            "                \"GeoObject\": {\n" +
            "                    \"Point\": {\n" +
            "                        \"pos\": \"37.611347 55.760241\"\n" +
            "                    }\n" +
            "                }\n" +
            "            },\n" +
            "            {\n" +
            "                \"GeoObject\": {\n" +
            "                    \"Point\": {\n" +
            "                        \"pos\": \"37.593965 55.771575\"\n" +
            "                    }\n" +
            "                }\n" +
            "            }\n" +
            "        ]\n" +
            "    }\n" +
            "}\n" +
            "}";

JSONObject jsonObject = new JSONObject(text);
System.out.println(jsonObject
            .getJSONObject("response")
            .getJSONObject("GeoObjectCollection")
            .getJSONArray("featureMember")
            .getJSONObject(0)
            .getJSONObject("GeoObject")
            .getJSONObject("Point")
            .getString("pos"));

37.611347 55.760241

Answer 2

В Jackson есть аннотация com.fasterxml.jackson.annotation.JsonIgnoreProperties

У нее есть свойство com.fasterxml.jackson.annotation.JsonIgnoreProperties#ignoreUnknown , которое позволяет игнорировать все свойства json`a, которые не объявлены в dto.

Например:

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class GeographicCoordinatesDto {

Только вам необходимо проставить ее и на вложенные классы свойств

Есть возможность объявить такое поведение глобально через конфигурацию ObjectMapper:

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

READ ALSO
Как сделать update вместе insert в Spring Data?

Как сделать update вместе insert в Spring Data?

У меня имеется такая вот сущность:

359
Ошибка кодировки

Ошибка кодировки

При создании записи в БД через crud-приложение java кириллические символы в таблице юзеров (crud по юзерам) и в БД (в MySQLWorkbench) отображаются приблизительно...

352
Как найти ссылки в тексте? И их положение

Как найти ссылки в тексте? И их положение

ЗдравствуйтеЕсть текст моя программа делит его на предложения

300
DataSource в Intellij IDEA

DataSource в Intellij IDEA

В Intellij IDEA есть вкладка DatabaseВ ней можно добавить DataSource

395