java - 如果我们试图将 JSON 放入 hashmap 中,我们如何使用 jackson 处理 JSON 内部的 JSON?

标签 java json spring spring-boot jackson

我正在尝试将从 POST 请求作为字符串接收的 JSON 对象转换为 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 在键 attributeList 中包含另一个 json,而该附加 json 就是给我带来问题的原因。 如果我尝试使用上面的 JSON 调用 REST 服务的 post 方法,则会出现以下错误:

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]

我的post方法的相关代码如下:

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

请告诉我处理这种情况的正确方法。我是 Spring 的新手。

最佳答案

您不需要反序列化内部 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循环。

上述更改后代码会是什么样子:

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

关于java - 如果我们试图将 JSON 放入 hashmap 中,我们如何使用 jackson 处理 JSON 内部的 JSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61442860/

相关文章:

java - Java applet HTML 页面发生奇怪的事情

java - Saxonica 9.7.0.4 中的 com.saxonica.ptree.StylesheetPackager 发生了什么?

java - 如何在Hibernate+Spring+JUnit中测试事务回滚

java - Spring Boot 2 和 Spring 5 容器混淆

java - 项目编译需要一个没有在任何地方使用的类

java - 仅在字符串末尾删除空格(java)

java - 找不到具有不同 buildvariant 的包名称 "...."的匹配客户端

javascript - 如何在下拉列表中设置默认值 javascript

javascript - 动态填充 JSON 层次结构

java - MongoDB 和用户特定文档——Spring Security 后端