7

我有以下路线定义:

(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处理程序就会被调用。所以问题变成了我如何匹配除了扩展名之外的任何东西?

4

2 回答 2

12

Compojure 使用影响力进行路由匹配。点字符在影响力路线中具有特殊含义。它表示一个标记分隔符,类似于斜杠字符。以下字符在影响力中都具有此含义:/ . , ; ?.

这意味着类似的路由"/images/:id"不会匹配形式为/images/name.jpgsince的 uri imagesname并且jpg每个都代表 clout 中的单独标记。

为了匹配它,您可以根据需要以多种不同的方式组成您的路线。

如果您的所有图像都有.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] ...)

您也可以使用通配符,该通配符不太精确,可以匹配任何以 开头的 uri /images/

(GET "/images/*" [*] ...)
于 2010-10-21T19:02:03.290 回答
5

在这种情况下,真正的答案是 clojure-couchdb 库中存在错误。该补丁可在 github 上找到

它归结为将 {:as :byte-array} 映射参数和值添加到通过 clj-http 发送到沙发 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)))))
于 2010-10-21T20:57:44.897 回答