clojure ring 讓webapp變得毫無神祕感

首先要說明的是: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

三、若是進來出去都沒有,或者都有,就不做爲。

相關文章
相關標籤/搜索