clojure ring 让webapp变得毫无神秘感

首先要说明的是:clojure ring不是新思想,根据其git首页的描述,是从Python's WSGI and Ruby's Rack获得思想。最近写了几星期的clojure代码,觉得clojure ring实在是太简单了(这是褒义),所以忍不住介绍一下。

先看一下SPEC:https://github.com/ring-clojure/ring/blob/master/SPEC

总结起来就是一句话:你收到一个map,返回一个map,你的Handler就做这件事情。

那么中间件呢?就是包裹一下handler,在handler之前做点事,在handler之后做点事。

下面是假象的handler代码:

;request比如 {:uri / :query-string "a=1"}

(defn ahandler [request]
    {:status 200 :body "hello"}
)

中间件(相当于java的filter类似)

(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是定义基础的约定,在它的上面就是形形色色的框架了。

不过写这篇短博客的主要目的还是为了提醒自己不要和自己已知的java相混淆。

clojure和java的习惯差异很大,在java的世界里,当你获得一个Request(Response)对象,你把它传给其他类去加工,不管经过几个步骤,你的Request还是原来的Request,你的Response还是原来的Response,只不过内容变化而已。

clojure是不可变为主,所以它的request和response是每经过一个步骤都是新的。

(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的流程就是:

1、如果进来的时候subject没有session,出去的时候有了,说明经过了session操作,或者登录了,需要在cookie里面加上sessionid。

2、如果进来的时候subject有session,出去的时候没有了,说明session失效了,或者登出了,需要删除cookie

3、如果进来出去都没有,或者都有,就不作为。











你可能感兴趣的:(clojure ring 让webapp变得毫无神秘感)