2017-09-05 74 views
2

我一直在为此挣扎了两天以上,似乎找不到解决方案。Compojure显示图像的麻烦

因此,所有我试图做的就是在浏览器中显示图像,但是当我打电话端点,这是发生了什么:

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$2.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$1.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) 

上述任何线索是高度赞赏。

回答

3

的问题是,你打电话都ring.util.response/responsering.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"))))) 
+0

你是吧!看着(好的)来源,并计算出你的答案前2分钟...谢谢! – Sasha

0

如果你想显示图像,你最好与<img>链接到静态资产(通常是resources/)您的DIR返回的HTML页面。

如果你想下载文件,这里的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进去端点处使用此功能,希望它帮助。