Как мы можем обработать JSON внутри JSON с Джексоном, если мы пытаемся поместить его в хэш-карту? - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь преобразовать JSON объект, полученный в виде строки из запроса POST, в HashMap. Все работает нормально, пока я не добавлю еще один json в свою базу json, как показано ниже:

    {"contextUser": "user",
    "contextPassword": "password",
    "vault": "testVault",
    "type":  "A_Training",
    "name": "crudTest1",
    "revision": "A",
    "policy": "A_Training_Policy",
    "attributeList": {
        "A_Skill": "JAVA",
        "A_Duration": "45",
        "A_CostOfTraining": "1500"
      }
   }

Здесь моя база json содержит еще один json внутри ключа attributeList и этот дополнительный json является тем, что создает проблему для меня. Если я пытаюсь использовать метод сообщения моего REST-сервиса, используя приведенный выше JSON, это выдает ошибку ниже:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to java.lang.String
    at crud.CRUDController.saveBusDetails(CRUDController.java:78) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]...
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:105) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:879) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.5.RELEASE.jar:5.2.5.RELEASE]

Ниже приведен соответствующий код моего метода публикации:

ObjectMapper objectMapper = new ObjectMapper();
            HashMap<String, String> busObjMap = objectMapper.readValue(busData, HashMap.class);
            HashMap<String, String> attributeList = objectMapper.readValue(busObjMap.get("attributeList"), HashMap.class);
            Iterator it=busObjMap.entrySet().iterator();
            System.out.println("Business Object values:");
            while(it.hasNext()) {
                Map.Entry<String, String> map= (Entry<String, String>) it.next();
                System.out.println(map.getKey()+": "+map.getValue());
            }
            it=attributeList.entrySet().iterator();
            System.out.println("Attribute values:");
            while(it.hasNext()) {
                Map.Entry<String, String> map= (Entry<String, String>) it.next();
                System.out.println(map.getKey()+": "+map.getValue());
            }

Пожалуйста дайте мне знать правильный способ справиться с такой ситуацией. Я новичок в весне.

Ответы [ 2 ]

2 голосов
/ 27 апреля 2020

Вам не нужно десериализовать внутренний JSON Object еще раз. Он уже десериализован до Map экземпляра. Итак, все, что вам нужно, это приведение.

  1. Десериализация полезной нагрузки до Map<String, Object>, что безопасно с использованием класса com.fasterxml.jackson.core.type.TypeReference.
  2. Приведение внутреннего объекта к Map<String, String> только если JSON полезная нагрузка подтверждена. В противном случае проблема с приведением снова возникнет.
  3. Чтобы выполнить итерации по Map, не создавайте Iterator объект. Используйте Java 8 Stream API или обычный for l oop.

Как может выглядеть код после вышеуказанных изменений:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.IOException;
import java.util.Map;

public class JsonApp {

    public static void main(String[] args) throws IOException {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper objectMapper = new ObjectMapper();
        // read as Map
        Map<String, Object> busObjMap = objectMapper.readValue(jsonFile, new TypeReference<Map<String, Object>>() {});
        // Inner object is already deserialised as well into Map
        Map<String, String> attributeList = (Map<String, String>) busObjMap.get("attributeList");
        System.out.println("Business Object values:");
        for (Map.Entry<String, Object> entry : busObjMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }

        System.out.println("Attribute values:");
        for (Map.Entry<String, String> entry : attributeList.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }
}
0 голосов
/ 26 апреля 2020

Создайте класс, соответствующий вашей json структуре, используйте его, лучше с точки зрения читабельности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...