如何在 Clojure/Compojure/Ring 中将映射转换为 URL 查询字符串?

Posted

技术标签:

【中文标题】如何在 Clojure/Compojure/Ring 中将映射转换为 URL 查询字符串?【英文标题】:How to convert map to URL query string in Clojure/Compojure/Ring? 【发布时间】:2012-04-02 11:39:54 【问题描述】:

在 Clojure / Compojure 中,如何将映射转换为 URL 查询字符串?

:foo 1 :bar 2 :baz 3

foo=1&bar=2&baz=3

在 compojure 中是否有任何实用方法可以做到这一点?

【问题讨论】:

Clojure building of URL from constituent parts的可能重复 【参考方案1】:

类似:

(defn params->query-string [m]
     (clojure.string/join "&" (for [[k v] m] (str (name k) "=" v))))

应该这样做......

REPL 会话:

user> (defn params->query-string [m]
         (clojure.string/join "&" 
            (for [[k v] m] 
               (str (name k) "="  (java.net.URLEncoder/encode v)))))
#'user/params->query-string
user> (params->query-string :foo 1 :bar 2 :baz 3)
"foo=1&bar=2&baz=3"
user> 

【讨论】:

我还可以在地图中的每个值上使用java.net.URLEncoder.encode,即(for [[k v] m] (str (name k) "=" (java.net.URLEncoder/encode v))) 我做了同样的事情,但是有没有实用的方法可以做到这一点? @Sathish Hiccup 提供了一些 relevant functionality: (hiccup.util/url "/hello" :a 1 :b 2) => "/hello?a=1&b=2"。如果你不想仅仅为单个实用函数添加对 Hiccup 的依赖,那么自己编写函数真的没什么大不了的。 我很抱歉,但如果主要答案没有通过省略编码来正确处理,那将是一件大事。人们会犯错误;使用图书馆。 @andrew cooke - 同意 - 我用 user100464 的建议更新了我的答案。【参考方案2】:

是的,已经有一个不涉及 Hiccup 或滚动您自己的 string/join/URLEncoder 函数的实用程序:

user=> (ring.util.codec/form-encode :foo 1 :bar 2 :baz 3)
"foo=1&bar=2&baz=3"
user=>

Compojure 依赖于 ring/ring-core,其中包括 ring.util.codec,所以你已经拥有了。

【讨论】:

【参考方案3】:
(defn to-query [inmap]
    (->> inmap
       (map (fn [[f s]] (str (name f) "=" (java.net.URLEncoder/encode (str s) "UTF-8"))))
       (clojure.string/join '&)
       ))

此代码从关键字中删除 ':',但如果关键字是数字,则会引发异常。

(to-query :foo 1 :bar 2 :baz 3)
=> "foo=1&bar=2&baz=3"

【讨论】:

以上是关于如何在 Clojure/Compojure/Ring 中将映射转换为 URL 查询字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何在表单提交后保留文本(如何在提交后不删除自身?)

如何在异步任务中调用意图?或者如何在 onPostExecute 中开始新的活动?

在 Avkit 中如何使用这三行代码,以及如何将音乐静音”

如何在 JDBC 中启动事务?

如何在 Fragment 中调用 OnActivityResult 以及它是如何工作的?

如何使用 Firebase 在 Web 上托管 Flutter?它的效果如何?