访问 Compojure 查询字符串
Posted
技术标签:
【中文标题】访问 Compojure 查询字符串【英文标题】:Accessing Compojure query string 【发布时间】:2012-02-16 07:19:54 【问题描述】:我正在尝试从 url 查询字符串中提取一个值,但是我可以返回我认为是地图的内容,但是当我使用以下代码时,它不会按预期处理它。谁能建议我如何访问返回的查询字符串数据结构中的特定值?
http://localhost:8080/remservice?foo=bar
(defroutes my-routes
(GET "/" [] (layout (home-view)))
(GET "/remservice*" params :query-params (str (:parameter params))))
【问题讨论】:
这里有两个问题。这个函数有参数吗?什么是 GET?这就是我问的原因。你应该能够从 params 中提取你需要的东西,但是 params 在哪里呢? 【参考方案1】:您需要将处理程序包装在compojure.handler/api
或compojure.handler/site
中,以添加适当的中间件以访问:query-params
。这曾经在defroutes
中自动发生,但现在不再发生。一旦你这样做了,params :query-params
解构表单将导致params
绑定到"foo" "bar"
,当你用foo=bar
作为查询字符串点击/remservice
时。
(或者您可以手动添加 wrap-params
等 - 它们位于各种 ring.middleware.*
命名空间中;请参阅 the code of compojure.handler
(链接到 Compojure 1.0.1 中的相关文件)了解它们的名称。)
例如
(defroutes my-routes
(GET "/remservice*" params :query-params
(str params)))
(def handler (-> my-routes compojure.handler/api))
; now pass #'handler to run-jetty (if that's what you're using)
如果您现在点击http://localhost:8080/remservice?foo=bar
,您应该会看到"foo" "bar"
——您的查询字符串的文本表示已解析为Clojure 映射。
【讨论】:
好的,我已经让它返回了一个地图,但是我似乎无法访问各个条目,例如(:foo params) 或 (get params foo) 或 (map :foo params) 不返回任何内容。我认为这是我对这个地图结构的主要困惑。 这是因为密钥以字符串形式保存——您需要使用(get params "foo")
。或者,您可以使用:params
代替:query-params
——Compojure 的api
添加到wrap-keyword-params
中间件中,因此:params
映射是“键化”的——但请注意:params
包括这两种类型的参数(另一个是表单参数;查询参数覆盖:params
映射中的表单参数)。
你怎么做这样的事情:/users/123?sort=desc 我有参数传递给向量。【参考方案2】:
在 compojure 1.2.0 的默认应用程序中,查询字符串中间件似乎默认包含在内。您可以这样检查请求。
(GET "/" request (str request))
它应该有很多东西,包括params
键。
. . . :params :key1 "value1" :key2 "value2 . . .
因此,您可以包含一个标准的 Clojure 解构表单来访问响应中的查询参数。
(GET "/" params :params (str params))
您的页面应如下所示。
"key1" "value1", "key2" "value2"
然而,正如上面 Michal 的评论中所指出的,键被转换为字符串,如果您想访问它们,您需要使用 get 函数而不是更方便的符号查找。
(GET "/" params :params (get params "key1"))
;;the response body should be "value1"
【讨论】:
【参考方案3】:使用compojure 1.6.1
HTTP-request-destructuring 对我来说是这样的:
-
在
:dependencies
中添加 [ring/ring-defaults "0.3.2"]
在 project.clj
中(因为 compojure.handler
命名空间自 1.2 起已弃用,取而代之的是 [ring-defaults]
)
在:require
中添加[ring.middleware.defaults :refer :all]
在your.routes.namespace
在your.routes.namespace
中添加(def site (wrap-defaults app site-defaults))
,其中app
是通过(defroutes app ...
声明的
在project.clj
中添加:ring :handler your.routes.namespace/site
【讨论】:
【参考方案4】:我很幸运在 compojure 1.1.5 中不需要包装器并且能够使用 :as
指令
(GET "/tweet/:folder/:detail" [folder detail :as req]
(twitter-controller/tweet folder detail (-> req :params :oauth_verifier))
【讨论】:
以上是关于访问 Compojure 查询字符串的主要内容,如果未能解决你的问题,请参考以下文章