The first thing to note is that the Clojure ring is not a new idea, according to the description of its Git homepage, which is derived from Python's WSGI and Ruby's rack. Recently wrote a few weeks of Clojure code, think Clojure ring is too simple (this is commendatory), so can't help introduce.
Look at Spec:https://github.com/ring-clojure/ring/blob/master/spec first.
To summarize is a sentence: You receive a map, return a map, your handler do this thing.
So what about middleware? Just wrap up handler, do something before handler, and do something after handler.
Here is the handler code for the illusion:
Request for example {: URI/: Query-string "A=1"} (defn Ahandler [request] {: status 200:body "Hello"})
Middleware (similar to Java filter)
(Defn Amiddleware [Handler] (FN [request] (Let [New-request (dosomething request) Response (handler New-request)]; If you want to deal with response, deal with it here. )))
The role of middleware here is the above example, if the final handler directly with query-string is not very convenient, then you can use it in the middleware to generate a new key, such as Paras, and Paras is a map, which can be used directly (: a paras) Gets the value of a. The ring, of course, is the convention that defines the foundation on which the various frameworks are framed.
But the main purpose of writing this short blog is to remind yourself not to be confused with your known java.
Clojure and Java habits are very different, in the Java world, when you get a request (Response) object, you pass it to other classes to process, regardless of a few steps, your request or the original request, Your response is still the original response, but the content changes only.
The
Clojure is immutable, so its request and response are new for every step.
(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))))
The above code is my integrated ring and Apache Shiro a middleware, at the beginning of the time always feel modified response, return response can. But the rules of clojure are not so.
(Let [response {: Status 200:body "Hello"}] (assoc-in response [: Cookies:jsessionid] "xxxooo") (response)); Here is misunderstood, always think response has been modified, in fact (assoc-in response [: Cookies:jsessionid] "xxxooo") is the new response. Do not add response! at the end; (Let [response {: Status 200:body "Hello"}] (assoc-in response [: Cookies:jsessionid] "xxxooo")
The above shiro-body process is:
1, if come in time subject no session, out of time have, explain after the session operation, or login, need to add SessionID in the cookie.
2, if come in time subject have session, go out of time No, explain session invalid, or log out, need to delete cookie
3, if you come out without, or all have, do not act.
Clojure ring makes WebApp no mystery.