clojure-web中的resources

不管是springboot項目齐饮,還是我們每天都在玩的luminus項目闸昨,做web項目免不了處理一些資源文件,本篇介紹原因和常用案例医瘫。

Ring(一定要了解下)

Ring是一個Clojure Web程序庫铜邮,有點類似與Java的servlet萨蚕。
公司目前用的都是用luminus 框架new出來的web項目颗搂,也是用Ring把我們的代碼編譯到一個java servlet運行的担猛,所以必須去了解(有中文版)。但是本文只說Resources的使用丢氢。

Ring框架里對靜態(tài)資源的文檔介紹確實不多傅联,在靜態(tài)資源(Static Resources)

案例一:dev模式可以,打包后找不到文件

一些新手經(jīng)常會說:“我本地沒問題”疚察。是的蒸走,本地確實沒問題,所謂的沒問題的代碼是這樣的,
比如要拷貝resources里的一個文件

(with-open [in (io/input-stream (io/resource "abc/file.dat"))]   ;; resources/abc/file.dat
    (io/copy in (io/file "/path/to/your/target/path")))

這段代碼本地是沒問題稍浆,但是以jar方式運行就會找不到文件载碌。

這要了解下打包干了啥猜嘱,有點深。
簡單說就是本地運行時確實這個路徑下有這個文件嫁艇。但是打成jar以后可以解壓看看朗伶,這個路徑不是你腦子的那個路徑了。

  • 原因:jar本身就是一個文件步咪,不是一個目錄论皆,代碼中拼接的文件路徑變成了xxx.jar!abc/file.dat,這是一個偽地址,解壓下jar也可以看到猾漫,確實不是這樣的点晴,所以找不到路徑。

那怎么寫呢悯周?就是用io/resource代替赤裸裸的路徑,下面這個函數(shù)接收一個路徑粒督,只要是項目根目錄下resouces里的地址,就不會有問題禽翼。

(defn- reader-excel-template
  "讀入模板"
  [t-path]
  (let [resource (io/resource t-path)
        file-name (str (common-utils/uuid) ".xlsx")]
    (with-open [in (io/input-stream resource)]
      (io/copy in (io/file file-name)))
    (io/as-file file-name)))

案例二:寫個接口把resources里的文件讀出來

比如我們resources里有這些文件屠橄。

$ tree -c -L 3
.
├── doc
├── migrations
├── public
│   ├── img
│   │   ├── img_index.png
│   │   ├── img_index_icon.png
│   │   └── warning_clojure.png
└── sql
    ├── queries.sql

寫一個接口:

["/download"
     {:get {:summary "downloads a file"
            :swagger {:produces ["image/png"]}
            :handler (fn [_]
                       {:status  200
                        :body    (-> "public/img/warning_clojure.png"
                                     (io/resource)
                                     (io/input-stream))})}}]

上面這個接口,可以是resources目錄里的任意文件闰挡,只是我們按照常規(guī)放在了public目錄里了锐墙。瀏覽器訪問這個接口時,像pdf长酗,圖片溪北,視頻等瀏覽器會直接打開,其他不支持的格式夺脾,會開始下載之拨。
如果格式明確,向讓調(diào)用者知道類型劳翰,可以在handler指定類型,比如這個獲取圖片的敦锌,可以加:

  :headers {"Content-Type" "image/png"}

案例三:把靜態(tài)文件讓jar服務(wù)帶起來

我們有個build好的前端項目馒疹,當(dāng)然包括了index.html,js,css,images等佳簸。想要讓jar啟動時,作為server同時把這個前端項目颖变,不需要使用nginx生均,python等。

  • 前端代碼全部復(fù)制到resources/public目錄下腥刹。
    可能如下:
$ pwd
/Users/mahaiqiang/git/redcreation/chutian/src/clj-backend/resources/public

$ ll
total 352
-rw-r--r--  1 mahaiqiang  staff    96K Sep  8 16:00 256x256.icns
-rw-r--r--  1 mahaiqiang  staff   1.7K Sep  8 16:00 32x32.icns
-rw-r--r--  1 mahaiqiang  staff   1.3K Sep  8 16:00 asset-manifest.json
-rw-r--r--  1 mahaiqiang  staff   5.7K Sep  8 16:00 electron.js
-rw-r--r--  1 mahaiqiang  staff    40K Sep  8 16:00 icon.png
-rw-r--r--  1 mahaiqiang  staff   536B Sep  8 16:00 index.html
-rw-r--r--  1 mahaiqiang  staff   532B Sep  8 16:00 log.js
-rw-r--r--  1 mahaiqiang  staff   284B Sep  8 16:00 manifest.json
-rw-r--r--  1 mahaiqiang  staff   525B Sep  8 16:00 preload.js
-rw-r--r--  1 mahaiqiang  staff   1.8K Sep  8 16:00 product.js
drwxr-xr-x  5 mahaiqiang  staff   160B Sep  8 16:00 static

  • 配置handler马胧,用warp-resource函數(shù)把靜態(tài)資源加進(jìn)來。
(:require [ring.middleware.resource :as resource])

(defn- async-aware-default-handler
  ([_] nil)
  ([_ respond _] (respond nil)))

;;靜態(tài)資源放在resources/public/目錄下.注意:index.html里引入的static前不能有斜線這個絕對路徑
(defn- create-resource-handler []
  (resource/wrap-resource "/" {:root "resources/public"}))

(mount/defstate app-routes
  :start
  (ring/ring-handler
   (ring/router
    [(conj (base/service-routes)
           (base/swagger-routes)
           (api-public-routes)
           (api-routes)
           (api-callback-routes)
           (admin-routes)
           (admin-pulic-routes))])
   (ring/routes
    (create-resource-handler)
    (wrap-content-type (wrap-webjars async-aware-default-handler))
    (ring/create-default-handler))))

案例四:用jar代理本地指定目錄下的任意文件

我們可能把本地一個目錄當(dāng)成了文件服務(wù)器衔峰,上傳時上傳到這個目錄佩脊,上傳以后查看當(dāng)然也要能訪問到蛙粘。
Ring框架,也有靜態(tài)資源(Static Resources)威彰,寫了也不點進(jìn)去看出牧,搬過來吧.

Web應(yīng)用經(jīng)常需要服務(wù)靜態(tài)內(nèi)容,例如圖片或者樣式表.Ring提供了兩個中間件函數(shù)來做這個事情.

一個是wrap-file.它服務(wù)來自當(dāng)前文件系統(tǒng)一個目錄的靜態(tài)內(nèi)容:

(use 'ring.middleware.file)
(def app
  (wrap-file your-handler "/var/www/public"))

另一個是wrap-resource.它服務(wù)來自JVM classpath下的靜態(tài)內(nèi)容:

(use 'ring.middleware.resource)
(def app
  (wrap-resource your-handler "public"))

改造下我們的項目,

(:require [ring.middleware.resource :as resource]
              [ring.middleware.webjars :refer [wrap-webjars]])

(mount/defstate app-routes
  :start
  (ring/ring-handler
   (ring/router
    [(conj (base/service-routes)
           (base/swagger-routes)
           (api-routes))])
   (ring/routes
    (wrap-file (ring/create-resource-handler {:path "/"})
               "/Users/mahaiqiang/Downloads/")  ;;把本地下載目錄當(dāng)成文件存儲服務(wù)器
    (wrap-content-type (wrap-webjars (constantly nil)))
    (ring/create-default-handler))))

案例三和案例四可以同時使用歇盼,不沖突舔痕。

推薦資料

Ring 靜態(tài)資源
Clojure Resources

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市豹缀,隨后出現(xiàn)的幾起案子伯复,更是在濱河造成了極大的恐慌,老刑警劉巖邢笙,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啸如,死亡現(xiàn)場離奇詭異,居然都是意外死亡氮惯,警方通過查閱死者的電腦和手機(jī)组底,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來筐骇,“玉大人债鸡,你說我怎么就攤上這事☆跷常” “怎么了厌均?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長告唆。 經(jīng)常有香客問我棺弊,道長,這世上最難降的妖魔是什么擒悬? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任模她,我火速辦了婚禮,結(jié)果婚禮上懂牧,老公的妹妹穿的比我還像新娘侈净。我一直安慰自己,他們只是感情好僧凤,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布畜侦。 她就那樣靜靜地躺著,像睡著了一般躯保。 火紅的嫁衣襯著肌膚如雪旋膳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天途事,我揣著相機(jī)與錄音验懊,去河邊找鬼擅羞。 笑死,一個胖子當(dāng)著我的面吹牛义图,可吹牛的內(nèi)容都是我干的祟滴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼歌溉,長吁一口氣:“原來是場噩夢啊……” “哼垄懂!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起痛垛,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤草慧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后匙头,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體漫谷,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年蹂析,在試婚紗的時候發(fā)現(xiàn)自己被綠了舔示。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡电抚,死狀恐怖惕稻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蝙叛,我是刑警寧澤俺祠,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站借帘,受9級特大地震影響蜘渣,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜肺然,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一蔫缸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧际起,春花似錦拾碌、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至它匕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間窖认,已是汗流浹背豫柬。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工告希, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烧给。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓燕偶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親础嫡。 傳聞我的和親對象是個殘疾皇子指么,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容