javascript - 使用 Jackson ObjectMapper 将 Java HashMap 序列化为 JSON

标签 javascript java json model-view-controller jackson

我正在开发一个 Spring Boot MVC 应用程序,该应用程序在前端使用 Thymeleaf 模板。

我正在尝试将 MVC 模型中的 HashMap 绑定(bind)到 Thymeleaf 模板之一中的 JavaScript 变量。这是迄今为止所做的:-

  1. 在我的 MVC Controller 类中,我创建了一个 HashMap,它表示按类别组织的用户技能。 Skill 类是一个包含 name 和 id 属性的数据对象:-

    Map<String, List<Skill>> skillsMap = new HashMap();

  2. 我用所有类别和技能信息填充了此 map ,然后将其添加到我的模型中:-

    model.addAttribute("skillsMap", skillsMap);

  3. 在脚本部分的 Thymeleaf 模板上,我尝试将此 HashMap 绑定(bind)到变量。作为第二步,我尝试从 map 中检索列表之一并分配给第二个变量:-

    var skillsMapMap = [[${skillsMap}]];

    var adminList = skillsMapMap.get('Admin');

  4. 当我调试它时,我可以看到 HashMap 正在被读取,并且正在尝试将其绑定(bind)到我的 JavaScript 变量:-

    var skillsMapMap = {Languages=[Python, SQL, PL/SQL, Java], Databases=[MySQL, Oracle, Mongo], Editors=[Word, TextPad, Notepad]};

乍一看这看起来不错,我可以看到它包含我的所有数据,但它抛出以下错误:-

Uncaught Syntax Error: invalid shorthand property initializer
  • 经过研究,我意识到导致此错误的原因是 Java 默认情况下不会以有效的 JSON 格式序列化映射,因此尝试绑定(bind)到 JavaScript 变量失败。因此,我没有像步骤 2 中那样直接将 HashMap 添加到模型中,而是添加了一些代码以使用 Jackson 将其首先转换为 JSON 字符串:-

    
    //Populate the map with all required data then....
    
    String objectMapper = null;
    try {
        objectMapper = new ObjectMapper().writeValueAsString(skillsMap);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
    model.addAttribute("skillsMap", objectMapper);```
    
  • 这次当我尝试将其绑定(bind)到我的 JavaScript 变量时,当我在浏览器中调试时,该对象看起来像这样:-

  • var skillsMapJson = {&quot;Languages_OD&quot;:[{&quot;id&quot;:66,&quot;name&quot;:&quot;SQL&quot;},{&quot;id&quot;:67,&quot;name&quot;:&quot;PL/SQL&quot;}], etc, etc};

    JSON 现在看起来有效,但所有引号都被转义,并且现在引发不同的异常:-

    ```Uncaught SyntaxError: Unexpected token &```
    

    我觉得如果 JSON 字符串包含实际的引号而不是 ",Map 将成功绑定(bind)到我的变量。我将不胜感激有关如何处理此问题的任何建议。非常感谢您的阅读。

    编辑:下面添加的错误屏幕截图:-

    JSON encoding issue in JavaScript variable

    最佳答案

    我最终确实解决了这个问题,因此我提供了一个解决方案,以防它对其他人有帮助。但是,我觉得该解决方案有点“hacky”,因此欢迎任何进一步改进此问题或提供更优雅的解决方案的答案。

    问题在于我尝试从模型中检索 map 并将其分配给 JavaScript 变量的方式。最初,我尝试这样做:-

    var skillsMapRawString = [[${skillsMapJson}]];
    

    问题在于,这种引用 SkillsMapJson 的方式会强制 JavaScript 将其视为对象,并且在尝试将其反序列化为 JSON 时无法处理原始帖子中描述的编码问题。因此,上面的行抛出了异常“意外的 token &”。

    通过在对象引用周围添加单引号,JavaScript 被迫将 SkillsMapJson 视为字符串而不是对象:-

    var skillsMapRawString = '[[${skillsMapJson}]]';
    

    上面的变量赋值现在可以成功工作,但是我们仍然存在问题,它包含编码的引号,这阻止了它被解析为 JSON 对象。这感觉有点像黑客,因为我通过对字符串进行全局替换来解决这个问题:-

    var skillsMapJSONString = skillsMapRawString.replace(/&quot;/g, "\"");
    

    替换了之前导致问题的编码部分后,字符串现在可以解析为 JSON:-

    var skillsMapParsed = JSON.parse(skillsMapJSONString);
    

    最后,我已成功将列表映射分配给 JavaScript 变量! :)

    关于javascript - 使用 Jackson ObjectMapper 将 Java HashMap 序列化为 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58714576/

    相关文章:

    java - 为什么 Eclipse 不允许我为 2.1 EJB 项目选择 EJB 客户端 JAR?

    java - 有没有一种方法可以在 Spring Boot 应用程序中自定义 JPA 实体的仅一个特定 String 类型字段的序列化?

    java - 如何正确地向 sip 服务器重新注册?

    ios - 使用 Swift、AlamoFire 和 SwiftyJSON 解析 JSON 数据

    java - 将模型类中的数据赋值给数组,并根据传入的数据发送通知给用户

    javascript - 在选项选择 CSHTML 上显示/隐藏类

    Javascript 构造函数

    javascript - 即使状态更新也显示之前的内容 5 秒?

    json - d3.geo : Path vs. 投影

    javascript - 渲染后如何替换 Angular 组件标签?