我有以下路线定义:
(require '[compojure.core :as ccore]
'[ring.util.response :as response])
(def *main-routes*
(ccore/defroutes avalanche-routes
(ccore/GET "/" [] "Hello World 2")
(ccore/GET "/images/:id" [id] (get-image-response id))))
在此示例中,请求/
的工作方式与魅力相似,并返回预期的Hello World 2
。
get-images-response方法的定义如下:
(defn get-image-response
[id]
(let [record (db/get-image id false)]
(-> (response/response (:data record))
(response/content-type (:content-type record))
(response/header "Content-Length" (:size record)))))
虽然我得到了404,但是二进制文件的服务还没有完成。有什么想法吗?
编辑:
好的,问题与/images/name.jpg
上正在请求图像的事实有关。一旦删除.jpg
,处理程序就会被调用。所以问题是如何匹配除扩展名之外的任何内容?
答案 0 :(得分:11)
Compojure使用clout进行路由匹配。点字符在clout路线中具有特殊含义。它表示一个标记分隔符,类似于斜杠字符。以下字符在clout中都具有此含义:/ . , ; ?
。
这意味着"/images/:id"
之类的路由与/images/name.jpg
形式的uri不匹配,因为images
,name
和jpg
各自代表一个单独的令牌在影响力。
为了与之匹配,您可以根据需要以多种不同的方式撰写路线。
如果您的所有图片都有.jpg
扩展名,那么最简单的方法就是:
(GET "/images/:id.jpg" [id] ...)
如果扩展名有所不同,您可以执行以下操作:
(GET "/images/:name.:extension" [name extension] ...)
如果要限制扩展名,可以将compojure / clout传递给正则表达式:
(GET ["/images/:name.:ext", :ext #"(jpe?g|png|gif)"] [name ext] ...)
你也可以使用通配符,它不太精确,可以匹配任何以/images/
开头的uri:
(GET "/images/*" [*] ...)
答案 1 :(得分:4)
在这种情况下,真正的答案是clojure-couchdb库中存在一个错误。该补丁可用on github here。
归结为将{:as:byte-array}映射参数和值添加到通过clj-http发送到couch的api的请求。
我的代码中的另一个问题是ring
在呈现字节数时并不真正知道如何处理字节数组。我只是将字节数组包装成java.io.ByteArrayInputStream
而不是修补环。以下是处理下载的完整代码:
(defn get-image-response
[id]
(let [record (db/get-image id false)]
(-> (response/response (new java.io.ByteArrayInputStream (:data record)))
(response/content-type (:content-type (:content-type record)))
(response/header "Content-Length" (:size record)))))