Как преобразовать карту в строку запроса URL в Clojure/Compojure/Ring?

Как в Clojure/Compojure преобразовать карту в строку запроса URL?

{:foo 1 :bar 2 :baz 3}

to

foo=1&bar=2&baz=3

Есть ли какой-нибудь полезный метод для этого в compojure?


person Sathish    schedule 16.03.2012    source источник
comment
Возможный дубликат Clojure, создающий URL-адрес из составных частей   -  person Brad Koch    schedule 21.02.2017


Ответы (3)


Да, для этого уже есть утилита, которая не требует 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.util.codec, поэтому он у вас уже есть.

person Lispnik    schedule 13.04.2012

Что-то типа:

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

должен сделать это...

РЕПЛ-сеанс:

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> 
person sw1nn    schedule 16.03.2012
comment
Я также мог бы использовать java.net.URLEncoder.encode для каждого значения на карте, то есть (for [[k v] m] (str (name k) "=" (java.net.URLEncoder/encode v))). - person user100464; 17.03.2012
comment
Я сделал то же самое, но есть ли служебный метод для этого? - person Sathish; 17.03.2012
comment
@Sathish Hiccup предоставляет некоторые соответствующие функции: (hiccup.util/url "/hello" {:a 1 :b 2}) => "/hello?a=1&b=2". Если вы не хотите добавлять зависимость от Hiccup только для одной служебной функции, самостоятельное написание функции не представляет большого труда. - person Matthias Benkard; 17.03.2012
comment
извините, но это большая проблема, если основной ответ не делает это правильно, опуская кодировку. люди делают ошибки; использовать библиотеку. - person andrew cooke; 13.04.2012
comment
@andrew cooke - согласен - я обновил свой ответ предложением пользователя 100464. - person sw1nn; 13.04.2012

(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"
person wendyL    schedule 14.05.2019