Строка Json для объекта Java с динамическими ключами

Я хочу вставить ответ REST API на объект Java. Мой образец ответа, как показано ниже.

    {
        "key1": [
          {
            "name": "test1",
            "id": "id1",            
          }
        ],
        "key2": [
          {
            "name": "test2",
            "id": "id2",            
          },
          {
            "name": "test3",
            "id": "id3", 
          }
        ]
      }

Для этого я создал класс «Пользователь» для повторяющегося объекта.

@Data
public class User {
    private String name;
    private String id;    
}

Тело ответа API принимает только Class<T>, и для этого я проанализировал Map.class эту функцию, поскольку я хочу вставить данные ответа json в Map<String, List<User>> вместо объекта класса java.

public Mono<Map> getUserInfo(String number) {
        return apiAdaptor.getRequest(urlConfiguration.getUserApi(), Map.class, true
                , number);
    }


public <T> Mono<T> getRequest(String url, Class<T> responseClass, boolean isDds,
                                  String... urlArgs) {
        return Mono.just(this.accessToken)
                .flatMap(token -> this.webClient.get()
                        .uri(url, urlArgs)                     
                        .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                        .exchange()
                        .flatMap(clientResponse -> getClassResponse(clientResponse, responseClass, isDds))                        
                );
    }


private UserResponse handleSuccess(Map map) {        
        Map<String, List<User>> apiRes = map;
}

Но когда я перебирал ответ API (apiRes), он выдавал «java.util.LinkedHashMap не может быть передан пользователю». Как я проверил, если Джексон не может определить точный формат, он автоматически преобразуется в «LinkedHashMap». Пожалуйста помоги.

Обратите внимание, что я новичок в разработке Java.

Можете ли вы добавить, что означает, что тело ответа API принимает только Class<T> ? Если вы определяете объект как Map, это Map (то есть LinkedHashMap), и никакой дополнительной информации о типе не будет. Каждое комплексное значение также будет Map, и его невозможно преобразовать в User.

pirho 13.12.2020 21:21

пожалуйста, опубликуйте свой код, который вы используете, который дает вашу ошибку

Toerktumlare 13.12.2020 22:42

@pirho обновил вопрос.

udith 14.12.2020 02:35

@Toerktumlare обновил вопрос.

udith 14.12.2020 02:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
1
4
1 096
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не уверен, какой Httpclient вы используете для своей разработки. Однако с клиентом RestTemplate вы делаете, как показано ниже.

Map<String, List<User>> responseMap= new HashMap<>();
ResponseEntity<Map<String, List<User>>> response =new RestTemplateBuilder().build().getForEntity(url, responseMap.getClass());

Я использовал конструктор, чтобы использовались конвертеры сообщений по умолчанию.

Ответ принят как подходящий

Один трюк состоит в том, чтобы объявить собственный класс, чтобы сохранить универсальные типы для правильной компиляции и приведения. Итак, как:

@SuppressWarnings("serial")
public class DynKeyUserMap extends HashMap<String, List<User>> {}

Затем вместо использования Map.class используйте DynKeyUserMap.class, чтобы предотвратить проблемы с кастингом.

необходимо жестко запрограммировать выше созданный класс для модульного тестирования. не могли бы вы объяснить, как создать экземпляр для вышеуказанного. я пробовал ниже одного, но он показывает ошибку компиляции. DynKeyUserMap dynKeyUserMap = new HashMap<String, List<User>>();

udith 17.12.2020 03:42

@udith Это просто DynKeyUserMap dynKeyUserMap = new DynKeyUserMap();?

pirho 17.12.2020 07:01

Другие вопросы по теме