Обслуживание файлов изображений из каталога src - ошибка 404 - PullRequest
0 голосов
/ 15 января 2019

Я создал сайт в Clojure , Пьедестал и Boot Cljs . Учебник, который я использовал, был следующим: http://pedestal.io/guides/hello-world-content-types

Тогда я пытался добавить на сайт изображение, которое не было показано в руководстве. Я положил изображение a455.jpg в папку src. Я заметил, что в файле build.boot ключ :resources-paths установлен в папку src.

s@lokal:~/Dropbox$ tree ~/Dropbox/clojure-boot-heists//home/s/Dropbox/clojure-boot-heists/
├── build.boot
├── favicon.ico
├── profile.boot
├── project.clj
├── src
│   ├── a455.jpg
│   ├── favicon.ico
│   └── main.clj
└── target
    └── classes

-

s@lokal:~/Dropbox$ cat ~/Dropbox/clojure-boot-heists/build.boot 
(set-env!
 :resource-paths #{"src"}
 :dependencies   '[[onetom/boot-lein-generate "0.1.3" :scope "test"]
                   [io.pedestal/pedestal.service "0.5.1"]
                   [io.pedestal/pedestal.route   "0.5.1"]
                   [io.pedestal/pedestal.jetty   "0.5.1"]
                   [org.clojure/data.json        "0.2.6"]
                   [org.slf4j/slf4j-simple       "1.7.21"]])
(require 'boot.lein)
(boot.lein/generate)
s@lokal:~/Dropbox$ 

Таким образом, папка src в этом приложении похожа на папку public в обычных веб-приложениях. Не правда ли?

Я протестировал это веб-браузер, curl и Clojure response-for функции. Сайт работал, но без изображения. Вот вы curl результаты:

s@lokal:~/Dropbox$ curl -si -H "Accept: text/html" http://localhost:8890
HTTP/1.1 200 OK
Date: Mon, 14 Jan 2019 23:22:09 GMT
Strict-Transport-Security: max-age=31536000; includeSubdomains
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Type: text/html
Transfer-Encoding: chunked
Server: Jetty(9.3.8.v20160314)

<!doctype html>
<html lang='pl'>
<head>
<meta charset='utf-8'>
<title>Hi world!</title>
</head>
<body>
<img src='a455.jpg'>
</body>
</html>

-

s@lokal:~/Dropbox$ curl -si -H "Accept: text/html" http://localhost:8890/a455.jpg
HTTP/1.1 404 Not Found
Date: Mon, 14 Jan 2019 23:22:27 GMT
Content-Type: text/plain
Transfer-Encoding: chunked
Server: Jetty(9.3.8.v20160314)

А вот и вы приложение

(ns main
  (:require [clojure.data.json :as json]
            [io.pedestal.http :as http]
            [io.pedestal.http.route :as route]
            [io.pedestal.http.content-negotiation :as conneg]))

(defn ok [body]
  {:status 200 :body body})

(defn not-found []
  {:status 404 :body "Not found\n"})

(defn main-for [nm]
  (cond
    (unmentionables nm) nil
    (empty? nm) "<!doctype html>
<html lang='pl'>
<head>
<meta charset='utf-8'>
<title>Hi world!</title>
</head>
<body>
<img src='a455.jpg'>
</body>
</html>
"
    :else (str "Hello, " nm "\n")))


(defn respond-main [request]
  (let [nm (get-in request [:query-params :name])
        resp (main-for nm)]
    (if resp
      (ok resp)
      (not-found))))

(def supported-types ["text/html" "application/edn" "application/json" "text/plain"])
(def content-neg-intc (conneg/negotiate-content supported-types))
(defn accepted-type
  [context]
  (get-in context [:request :accept :field] "text/plain"))

(defn transform-content
  [body content-type]
  (case content-type
    "text/html" body
    "text/plain" body
    "application/edn" (pr-str body)
    "application/json" (json/write-str body)))

(defn coerce-to
  [response content-type]
  (-> response
      (update :body transform-content content-type)
      (assoc-in [:headers "Content-Type"] content-type)))

(def coerce-body
  {:name ::coerce-body
   :leave
         (fn [context]
           (cond-> context
                   (nil? (get-in context [:response :headers "Content-Type"]))
                   (update-in [:response] coerce-to (accepted-type context))))})

(def routes
  (route/expand-routes
    #{["/" :get [coerce-body content-neg-intc respond-main] :route-name :main]}))

(def service-map
  {::http/routes routes
   ::http/type   :jetty
   ::http/port   8890})

(defn start []
  (http/start (http/create-server service-map)))

(defonce server (atom nil))

(defn start-dev []
  (reset! server
          (http/start (http/create-server
                        (assoc service-map
                          ::http/join? false)))))

(defn stop-dev []
  (http/stop @server))

(defn restart []
  (stop-dev)
  (start-dev))

Как сделать так, чтобы изображение отображалось на сайте?

1 Ответ

0 голосов
/ 15 января 2019

Обычно изображения и другие элементы помещаются в папку ./resources. Они также могут быть в подпапках, в зависимости от точной конфигурации в lein или boot.

Вот пример проекта lein: http://git@gitlab.com:pedestal/hello.git

с примером файла ./resources/music.txt файл. Обычно они читаются с (:require [clojure.java.io :as io]) следующим образом:

(slurp (io/resource "music.txt"))

как вы можете видеть из echo-intc в src/hello/core.clj. Вы можете увидеть доступ к файлу в действии, введя lein run, а затем перейдя в браузере на localhost:8890

...