首先要說明的是:clojure ring不是新思想,根據其git首頁的描述,是從Python's WSGI and Ruby's Rack得到思想。最近寫了幾星期的clojure代碼,以爲clojure ring實在是太簡單了(這是褒義),因此忍不住介紹一下。java
先看一下SPEC:https://github.com/ring-clojure/ring/blob/master/SPEC git
總結起來就是一句話:你收到一個map,返回一個map,你的Handler就作這件事情。github
那麼中間件呢?就是包裹一下handler,在handler以前作點事,在handler以後作點事。shell
下面是假象的handler代碼:apache
;request好比 {:uri / :query-string "a=1"} (defn ahandler [request] {:status 200 :body "hello"} )
中間件(至關於java的filter相似)cookie
(defn amiddleware [handler] (fn [request] (let [new-request (dosomething request) response (handler new-request)] ;若是要對response處理一下,就在這裏處理。 )))
中間件的做用這裏就舉上面的例子,若是最終handler直接用query-string總歸不太方便,那麼能夠在中間件裏面用它產生一個新的key,好比paras,而paras是一個map,這樣能夠直接用(:a paras)獲取a的值。固然ring是定義基礎的約定,在它的上面就是形形色色的框架了。session
不過寫這篇短博客的主要目的仍是爲了提醒本身不要和本身已知的java相混淆。框架
clojure和java的習慣差別很大,在java的世界裏,當你得到一個Request(Response)對象,你把它傳給其餘類去加工,無論通過幾個步驟,你的Request仍是原來的Request,你的Response仍是原來的Response,只不過內容變化而已。ui
clojure是不可變爲主,因此它的request和response是每通過一個步驟都是新的。spa
(defn shiro-body [handler request] (let [subject (build-subject request) session-before (.getSession subject false) response (.execute (build-callable)) session-after (.getSession (sec-util/get-subject))] (if (and (not session-before) session-after) (assoc-in response [:cookies :JSESSIONID] (create-cookie (.getId session-after))) (if (and (session-before) (not session-after)) (assoc-in response [:cookies :JSESSIONID] (create-cookie (.getId session-after) :http-only false :max-age 0)) response))))
上面的代碼是我集成ring和apache shiro的一個middleware,剛開始的時候總是以爲修改了response,返回response便可。可是clojure的規則不是這樣。
(let [response {:status 200 :body "hello"}] (assoc-in response [:cookies :JSESSIONID] "xxxooo") response)) ;這裏就誤會了,老是以爲response已經修改了,其實 (assoc-in response [:cookies :JSESSIONID] "xxxooo") 纔是新的response。不要在最後加response! ;這樣便可。 (let [response {:status 200 :body "hello"}] (assoc-in response [:cookies :JSESSIONID] "xxxooo"))
上面shiro-body的流程就是:
一、若是進來的時候subject沒有session,出去的時候有了,說明通過了session操做,或者登陸了,須要在cookie裏面加上sessionid。
二、若是進來的時候subject有session,出去的時候沒有了,說明session失效了,或者登出了,須要刪除cookie
三、若是進來出去都沒有,或者都有,就不做爲。