【问题标题】:serialize and deserialize Clojure ::namespaced-keywords in JSON在 JSON 中序列化和反序列化 Clojure ::namespaced-keywords
【发布时间】:2015-07-23 20:39:20
【问题描述】:

我正在尝试将一些 Clojure 数据结构序列化到一个持久数据库中,我目前为此使用 Chesire

假设我有一个包含命名空间关键字的地图,如下所示:

{:cemerick.friend/identity {:current friend, :authentications {friend {:identity friend, :roles #{:clojure-cms.handler/user}}}}}

它被序列化为 JSON,就像这样:

{"cemerick.friend/identity":{"current":"friend","authentications":{"friend":{"identity":"friend","roles":["clojure-cms.handler/user"]}}}}

当读回并序列化(使用关键字(parse-string data true))时,我得到以下信息:

{:cemerick.friend/identity {:current friend, :authentications {:friend {:identity friend, :roles [clojure-cms.handler/user]}}}}

如何解析这个 JSON 并获得与原始数据相同的数据?

注意this question 为我想要实现的目标提供了一些背景信息。

【问题讨论】:

    标签: json authentication serialization clojure


    【解决方案1】:

    查看tests in Chesire,很明显parse-string 的可选关键字参数将影响JSON 对象中的所有name 属性,而示例中的命名空间关键字等值属性则不会做作的。实际上,您的问题有两个:原始集合也没有正确转换回来。

    对于集合问题,你可以做的是编写一个自定义解码器,如Chesire documentation中所述。

    对于原来的问题,大概没有直接的办法,只能对返回的map进行后处理,找到:roles的值,然后把值变成关键字,像这样(未测试):

    (defn postprocess-json [authmap]
        (update-in authmap [:authentications :friend :roles] keyword))
    

    【讨论】:

    • 我希望也许可以使用其他东西(edn 也许,但我根本不知道)。我暂时接受你的回答。
    • 是的,您可以使用 edn,它会正确反序列化 set 和命名空间关键字。试试:(clojure.edn/read-string (pr-str {::namespaced #{:non-ns ::ns}}))
    • 尽管如此,我认为@schaueho 是您问题的正确答案:)
    • @nberger 很有趣。就我而言,我担心 JSON 兼容性(请参阅我原帖中的链接问题),你认为这可能是一个问题吗?
    • 嗯,是的,如果您使用 edn,它将不兼容 json。对不起,我没有得到完整的上下文......如果这个序列化的地图必须作为更大会话的一部分进入 redis,它也必须由节点应用程序反序列化,我看到两个选项:对整个使用 edn session (所以节点也应该使用它),或者如果只在 clojure 端需要这个映射,那么您仍然可以使用 edn 但您必须对其进行编码(b64?)以将其放入 json 映射中。有关如何进行编码的示例,请参阅this answer
    猜你喜欢
    • 2020-10-23
    • 2018-12-18
    相关资源
    最近更新 更多