Compojure 无法显示图像
Compojure trouble displaying an image
我已经为此苦苦挣扎了两天多,似乎没有找到解决方案。
所以我想做的就是在浏览器中显示图像,但是当我调用端点时会发生这种情况:
Cannot JSON encode object of class: class java.io.File
端点
(context "/servers" []
:datomic true
(GET "/:id/graph/:panel-type" {db :db user :user}
:summary "Return a server graph image"
:path-params [id :- Long
panel-type :- String]
(let [file-path (str panel-type ".png")
result (-> (response/response (clojure.java.io/file file-path))
(response/content-type "image/png")))]
(ok result)))) ;; ring.util.http-response
我是 compojure 的新手 API,但有些东西让我觉得中间件实现有问题 - 自定义格式?
中间件
(defn wrap-formats [handler]
(let [wrapped (wrap-restful-format
handler
{:formats [:json-kw :transit-json :transit-msgpack]})]
(fn [request]
;; disable wrap-formats for websockets
;; since they're not compatible with this middleware
((if (:websocket? request) handler wrapped) request))))
堆栈跟踪
com.fasterxml.jackson.core.JsonGenerationException: Cannot JSON encode object of class: class java.io.File: cpu.png
at cheshire.generate$generate.invokeStatic(generate.clj:152)
at cheshire.generate$generate.invoke(generate.clj:116)
at cheshire.generate$generate.invokeStatic(generate.clj:122)
at cheshire.generate$generate.invoke(generate.clj:116)
at cheshire.core$generate_string.invokeStatic(core.clj:74)
at cheshire.core$generate_string.invoke(core.clj:49)
at ring.middleware.format_response$make_json_encoder$fn__20198.invoke(format_response.clj:221)
at ring.middleware.format_response$wrap_format_response$fn__20186.invoke(format_response.clj:204)
at ring.middleware.keyword_params$wrap_keyword_params$fn__4302.invoke(keyword_params.clj:36)
at ring.middleware.nested_params$wrap_nested_params$fn__20350.invoke(nested_params.clj:89)
at ring.middleware.params$wrap_params$fn__4376.invoke(params.clj:67)
at compojure.api.middleware$wrap_options$fn__23551.invoke(middleware.clj:74)
at compojure.api.routes.Route.invoke(routes.clj:74)
at clojure.lang.Var.invoke(Var.java:381)
at compojure.core$routing$fn__4157.invoke(core.clj:185)
at clojure.core$some.invokeStatic(core.clj:2674)
at clojure.core$some.invoke(core.clj:2665)
at compojure.core$routing.invokeStatic(core.clj:185)
at compojure.core$routing.doInvoke(core.clj:182)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at compojure.core$routes$fn__4161.invoke(core.clj:192)
at clojure.lang.Var.invoke(Var.java:381)
at ring.middleware.reload$wrap_reload$fn__46696.invoke(reload.clj:39)
at selmer.middleware$wrap_error_page$fn__46709.invoke(middleware.clj:9)
at prone.middleware$wrap_exceptions$fn__46879.invoke(middleware.clj:126)
at buddy.auth.middleware$wrap_authentication$fn__44919.invoke(middleware.clj:42)
at buddy.auth.middleware$wrap_authorization$fn__44927.invoke(middleware.clj:94)
at ring.middleware.cors$handle_cors.invokeStatic(cors.clj:146)
at ring.middleware.cors$handle_cors.invoke(cors.clj:135)
at ring.middleware.cors$wrap_cors$fn__45217.invoke(cors.clj:160)
at ring.middleware.flash$wrap_flash$fn__45283.invoke(flash.clj:39)
at ring.middleware.session$wrap_session$fn__45465.invoke(session.clj:108)
at ring.middleware.keyword_params$wrap_keyword_params$fn__4302.invoke(keyword_params.clj:36)
at ring.middleware.nested_params$wrap_nested_params$fn__20350.invoke(nested_params.clj:89)
at ring.middleware.multipart_params$wrap_multipart_params$fn__45551.invoke(multipart_params.clj:172)
at ring.middleware.params$wrap_params$fn__4376.invoke(params.clj:67)
at ring.middleware.cookies$wrap_cookies$fn__45416.invoke(cookies.clj:175)
at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__45638.invoke(absolute_redirects.clj:47)
at ring.middleware.resource$wrap_resource$fn__45567.invoke(resource.clj:37)
at ring.middleware.content_type$wrap_content_type$fn__25387.invoke(content_type.clj:34)
at ring.middleware.default_charset$wrap_default_charset$fn__45610.invoke(default_charset.clj:31)
at ring.middleware.not_modified$wrap_not_modified$fn__25417.invoke(not_modified.clj:53)
at ring.middleware.x_headers$wrap_x_header$fn__45246.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__45246.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__45246.invoke(x_headers.clj:22)
at voltage.middleware$wrap_bearer_token$fn__46930.invoke(middleware.clj:72)
at ring.middleware.webjars$wrap_webjars$fn__45738.invoke(webjars.clj:40)
at voltage.middleware$wrap_internal_error$fn__46919.invoke(middleware.clj:37)
at immutant.web.internal.undertow$create_http_handler$reify__57634.handleRequest(undertow.clj:239)
at org.projectodd.wunderboss.web.undertow.async.websocket.UndertowWebsocket.handleRequest(UndertowWebsocket.java:107)
at io.undertow.server.session.SessionAttachmentHandler.handleRequest(SessionAttachmentHandler.java:68)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:802)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
非常感谢以上任何线索。
如果你想显示图像,你最好returnHTML页面<img>
链接到你的静态资产目录(通常resources/
).
如果你想下载文件,这里有一个Compojure-api处理程序的例子:
(ns example.app
(:require [clojure.java.io :as io]
[ring.util.response :as r]))
(defn file-download [name]
(let [filename (str "resources/" name)
bin (io/file filename)]
(-> (r/response (io/input-stream bin))
(r/header "Content-Type" "application/octet-stream")
(r/header "Content-Disposition" "attachment")
(r/header "Content-Length" (.length bin))
(r/status 200))))
在你的let
进入端点的地方调整并使用这个函数,希望它能有所帮助。
问题是您同时调用了 ring.util.response/response
和 ring.util.http-response/ok
:
(ok (ring.util.response/response "foo"))
=> {:status 200, :headers {}, :body {:status 200, :headers {}, :body "foo"}}
单独使用它们中的任何一个都有效:
(ns compojure.api.examples.handler
(:require [clojure.java.io :as io]
[compojure.api.sweet :refer :all]
[ring.middleware.format :refer [wrap-restful-format]]
[ring.util.http-response :refer :all]
[ring.util.response :as response]
[compojure.api.examples.domain :refer :all]
[schema.core :as s]))
(defn wrap-formats [handler]
(let [wrapped (wrap-restful-format
handler
{:formats [:json-kw :transit-json :transit-msgpack]})]
(fn [request]
;; disable wrap-formats for websockets
;; since they're not compatible with this middleware
((if (:websocket? request) handler wrapped) request))))
(def app
(wrap-formats
(api
(GET "/lisplogo" []
(-> (response/response (io/file "lisplogo_256.png"))
(response/content-type "image/png")))
(GET "/lisplogo2" []
(assoc-in (ok (io/file "lisplogo_256.png"))
[:headers "Content-Type"]
"image/png")))))
我已经为此苦苦挣扎了两天多,似乎没有找到解决方案。
所以我想做的就是在浏览器中显示图像,但是当我调用端点时会发生这种情况:
Cannot JSON encode object of class: class java.io.File
端点
(context "/servers" []
:datomic true
(GET "/:id/graph/:panel-type" {db :db user :user}
:summary "Return a server graph image"
:path-params [id :- Long
panel-type :- String]
(let [file-path (str panel-type ".png")
result (-> (response/response (clojure.java.io/file file-path))
(response/content-type "image/png")))]
(ok result)))) ;; ring.util.http-response
我是 compojure 的新手 API,但有些东西让我觉得中间件实现有问题 - 自定义格式?
中间件
(defn wrap-formats [handler]
(let [wrapped (wrap-restful-format
handler
{:formats [:json-kw :transit-json :transit-msgpack]})]
(fn [request]
;; disable wrap-formats for websockets
;; since they're not compatible with this middleware
((if (:websocket? request) handler wrapped) request))))
堆栈跟踪
com.fasterxml.jackson.core.JsonGenerationException: Cannot JSON encode object of class: class java.io.File: cpu.png
at cheshire.generate$generate.invokeStatic(generate.clj:152)
at cheshire.generate$generate.invoke(generate.clj:116)
at cheshire.generate$generate.invokeStatic(generate.clj:122)
at cheshire.generate$generate.invoke(generate.clj:116)
at cheshire.core$generate_string.invokeStatic(core.clj:74)
at cheshire.core$generate_string.invoke(core.clj:49)
at ring.middleware.format_response$make_json_encoder$fn__20198.invoke(format_response.clj:221)
at ring.middleware.format_response$wrap_format_response$fn__20186.invoke(format_response.clj:204)
at ring.middleware.keyword_params$wrap_keyword_params$fn__4302.invoke(keyword_params.clj:36)
at ring.middleware.nested_params$wrap_nested_params$fn__20350.invoke(nested_params.clj:89)
at ring.middleware.params$wrap_params$fn__4376.invoke(params.clj:67)
at compojure.api.middleware$wrap_options$fn__23551.invoke(middleware.clj:74)
at compojure.api.routes.Route.invoke(routes.clj:74)
at clojure.lang.Var.invoke(Var.java:381)
at compojure.core$routing$fn__4157.invoke(core.clj:185)
at clojure.core$some.invokeStatic(core.clj:2674)
at clojure.core$some.invoke(core.clj:2665)
at compojure.core$routing.invokeStatic(core.clj:185)
at compojure.core$routing.doInvoke(core.clj:182)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at compojure.core$routes$fn__4161.invoke(core.clj:192)
at clojure.lang.Var.invoke(Var.java:381)
at ring.middleware.reload$wrap_reload$fn__46696.invoke(reload.clj:39)
at selmer.middleware$wrap_error_page$fn__46709.invoke(middleware.clj:9)
at prone.middleware$wrap_exceptions$fn__46879.invoke(middleware.clj:126)
at buddy.auth.middleware$wrap_authentication$fn__44919.invoke(middleware.clj:42)
at buddy.auth.middleware$wrap_authorization$fn__44927.invoke(middleware.clj:94)
at ring.middleware.cors$handle_cors.invokeStatic(cors.clj:146)
at ring.middleware.cors$handle_cors.invoke(cors.clj:135)
at ring.middleware.cors$wrap_cors$fn__45217.invoke(cors.clj:160)
at ring.middleware.flash$wrap_flash$fn__45283.invoke(flash.clj:39)
at ring.middleware.session$wrap_session$fn__45465.invoke(session.clj:108)
at ring.middleware.keyword_params$wrap_keyword_params$fn__4302.invoke(keyword_params.clj:36)
at ring.middleware.nested_params$wrap_nested_params$fn__20350.invoke(nested_params.clj:89)
at ring.middleware.multipart_params$wrap_multipart_params$fn__45551.invoke(multipart_params.clj:172)
at ring.middleware.params$wrap_params$fn__4376.invoke(params.clj:67)
at ring.middleware.cookies$wrap_cookies$fn__45416.invoke(cookies.clj:175)
at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__45638.invoke(absolute_redirects.clj:47)
at ring.middleware.resource$wrap_resource$fn__45567.invoke(resource.clj:37)
at ring.middleware.content_type$wrap_content_type$fn__25387.invoke(content_type.clj:34)
at ring.middleware.default_charset$wrap_default_charset$fn__45610.invoke(default_charset.clj:31)
at ring.middleware.not_modified$wrap_not_modified$fn__25417.invoke(not_modified.clj:53)
at ring.middleware.x_headers$wrap_x_header$fn__45246.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__45246.invoke(x_headers.clj:22)
at ring.middleware.x_headers$wrap_x_header$fn__45246.invoke(x_headers.clj:22)
at voltage.middleware$wrap_bearer_token$fn__46930.invoke(middleware.clj:72)
at ring.middleware.webjars$wrap_webjars$fn__45738.invoke(webjars.clj:40)
at voltage.middleware$wrap_internal_error$fn__46919.invoke(middleware.clj:37)
at immutant.web.internal.undertow$create_http_handler$reify__57634.handleRequest(undertow.clj:239)
at org.projectodd.wunderboss.web.undertow.async.websocket.UndertowWebsocket.handleRequest(UndertowWebsocket.java:107)
at io.undertow.server.session.SessionAttachmentHandler.handleRequest(SessionAttachmentHandler.java:68)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange.run(HttpServerExchange.java:802)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
非常感谢以上任何线索。
如果你想显示图像,你最好returnHTML页面<img>
链接到你的静态资产目录(通常resources/
).
如果你想下载文件,这里有一个Compojure-api处理程序的例子:
(ns example.app
(:require [clojure.java.io :as io]
[ring.util.response :as r]))
(defn file-download [name]
(let [filename (str "resources/" name)
bin (io/file filename)]
(-> (r/response (io/input-stream bin))
(r/header "Content-Type" "application/octet-stream")
(r/header "Content-Disposition" "attachment")
(r/header "Content-Length" (.length bin))
(r/status 200))))
在你的let
进入端点的地方调整并使用这个函数,希望它能有所帮助。
问题是您同时调用了 ring.util.response/response
和 ring.util.http-response/ok
:
(ok (ring.util.response/response "foo"))
=> {:status 200, :headers {}, :body {:status 200, :headers {}, :body "foo"}}
单独使用它们中的任何一个都有效:
(ns compojure.api.examples.handler
(:require [clojure.java.io :as io]
[compojure.api.sweet :refer :all]
[ring.middleware.format :refer [wrap-restful-format]]
[ring.util.http-response :refer :all]
[ring.util.response :as response]
[compojure.api.examples.domain :refer :all]
[schema.core :as s]))
(defn wrap-formats [handler]
(let [wrapped (wrap-restful-format
handler
{:formats [:json-kw :transit-json :transit-msgpack]})]
(fn [request]
;; disable wrap-formats for websockets
;; since they're not compatible with this middleware
((if (:websocket? request) handler wrapped) request))))
(def app
(wrap-formats
(api
(GET "/lisplogo" []
(-> (response/response (io/file "lisplogo_256.png"))
(response/content-type "image/png")))
(GET "/lisplogo2" []
(assoc-in (ok (io/file "lisplogo_256.png"))
[:headers "Content-Type"]
"image/png")))))