如何在使用Metosin反序列化JSON时仅对顶层键应用key-decode-fn
仅转换JSON顶层键为关键字的实现方案
要实现仅将JSON顶层键转换为关键字、嵌套键保留字符串的需求,不需要复杂的Jackson自定义序列化器,直接分两步处理即可:
完整代码示例
(require '[jsonista.core :as json]) (import (com.fasterxml.jackson.datatype.joda JodaModule)) (def s "{\"name\":\"person1\",\"book\":\"Demo Book\",\"hash\":{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}}") ;; 创建不转换键的ObjectMapper,解析得到全字符串键的Map (def ^ObjectMapper raw-object-mapper (json/object-mapper {:modules [(JodaModule.)]})) ;; 定义转换顶层键的工具函数 (defn convert-top-keys-to-keywords [m] (into {} (map (fn [[k v]] [(keyword k) v])) m)) ;; 执行解析与转换,得到目标结果 (convert-top-keys-to-keywords (json/read-value s raw-object-mapper))
逻辑说明
- 第一步解析时,使用不带
:decode-key-fn参数的object-mapper,这样JSON里所有层级的键都会以字符串形式保留,包括嵌套的hash对象里的键。 - 第二步通过
convert-top-keys-to-keywords函数遍历顶层键值对,仅将顶层的字符串键转换为关键字,嵌套的结构完全保持原样。 - 最终输出结果完全符合需求:
{:book "Demo Book", :name "person1", :hash {"key3" "value3", "key2" "value2", "key1" "value1"}}
简化调用方式
如果希望代码更简洁,可以把解析和转换合并成一个函数:
(defn read-json-with-top-keywords [json-str] (let [raw-map (json/read-value json-str (json/object-mapper {:modules [(JodaModule.)]}))] (into {} (map (fn [[k v]] [(keyword k) v])) raw-map))) ;; 直接调用即可 (read-json-with-top-keywords s)
内容的提问来源于stack exchange,提问作者user51
相关产品推荐
相关产品推荐

