August 5, 2019
By: 马海强

clojure luminus开发之handler里的参数获取

推荐阅读文档

在handle前后,可以用(keys request)查看request里自己传入的参数,那么在handler里怎么获取这些参数呢,在Luminus中定义了三种与springMVC类似的参数关键词,对应关系如下:

mvcrequestluminus含义
@RequestParamquery-paramsparameters -> queryquery参数,URL后面问号的参数,或form的参数
@PathVariablepath-paramsparameters -> pathpath参数,URL中/的参数
@RequestBodybody-paramsparameters ->bodypost/put方法里的body参数

这三个keyword是ring自身的处理,是原始request里的参数,但是query-params参数被处理成map的key不是keywords,是普通的string,得用(query-params "id")这样来取值。因此推荐如下示例使用: 推荐从request的parameters中获取,关键字分别是query,path, body。 获取的例子:

  ;;非推荐方式
  ;;api返回结果: {"data": "path params: {:id \"1\"}\n query params: {\"name\" \"2\"}\n body params: {:message \"22\"}"}
  ["/path/bad/:id"
   {:post {:summary    "路径上传参--不推荐此方法获取--query参数key变成了str"
           :parameters {:path  {:id int?}
                        :query {:name string?}
                        :body  {:message string?}}
           :handler    (fn [{:keys [path-params query-params body-params]}]
                        {:status 200
                         :body   {:data (str "path params: " path-params
                                             "\n query params: " query-params
                                             "\n body params: " body-params)}})}}]

  ;;good handler api返回结果:
  #_{
    "code": 1,
    "message": "操作成功",
    "data": "path params: {:id 1},  query params: {:name \"2\"},  body params: {:message \"22\"} "
  }
  ["/path/good/:id"
   {:post {:summary    "路径上传参--GOOD--获取到3种map"
           :parameters {:path  {:id int?}
                        :query {:name string?}
                        :body  {:message string?}}
           :handler    (fn [{{:keys [body query path]} :parameters}]
                        (ok (format "path params: %s,  query params: %s,  body params: %s " path query body)))}}]


  ;;good handler, 接口里三种参数都有,并且想直接获取map中key的vals
  ;; api返回结果:
  #_{
    "code": 1,
    "message": "操作成功",
    "data": "path params 'id': 1, query params 'name': 2 , body params: {:message \"22\"} "
    }
  ["/path/good-all-params/:id"
   {:post {:summary    "路径上传参--GOOD--直接得到key的val"
           :parameters {:path  {:id int?}
                        :query {:name string?}
                        :body  {:message string?}}
           :handler    (fn [{{:keys [body]}          :parameters
                             {{:keys [id]} :path}    :parameters
                             {{:keys [name]} :query} :parameters}]
                        (ok (format "path params 'id': %s, query params 'name': %s , body params: %s " id name body)))}}]

原因分析:我们在handler.clj的ring/router后面使用[reitit.ring.middleware.dev :as dev]{:reitit.middleware/transform dev/print-request-diffs}方法打印出中间件的处理逻辑,

get-middleare

结果如下:

--- Middleware ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1"}

--- Middleware :reitit.ring.middleware.parameters/parameters ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1"}

--- Middleware :reitit.ring.middleware.muuntaja/format-negotiate ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1",
   +:muuntaja/request #muuntaja.core.FormatAndCharset
   {:charset "utf-8",
    :format "application/json",
    :raw-format "application/json"},
   +:muuntaja/response #muuntaja.core.FormatAndCharset
   {:charset "utf-8",
    :format "application/json",
    :raw-format "application/json"}}

--- Middleware :reitit.ring.middleware.muuntaja/format-response ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1",
   :muuntaja/request {:charset "utf-8",
                      :format "application/json",
                      :raw-format "application/json"},
   :muuntaja/response {:charset "utf-8",
                       :format "application/json",
                       :raw-format "application/json"}}

--- Middleware :reitit.ring.middleware.exception/exception ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1",
   :muuntaja/request {:charset "utf-8",
                      :format "application/json",
                      :raw-format "application/json"},
   :muuntaja/response {:charset "utf-8",
                       :format "application/json",
                       :raw-format "application/json"}}

--- Middleware :reitit.ring.middleware.muuntaja/format-request ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1",
   :muuntaja/request {:charset "utf-8",
                      :format "application/json",
                      :raw-format "application/json"},
   :muuntaja/response {:charset "utf-8",
                       :format "application/json",
                       :raw-format "application/json"},
   +:body-params {:message "22"}}

--- Middleware :reitit.ring.coercion/coerce-request ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :body-params {:message "22"},
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1",
   :muuntaja/request {:charset "utf-8",
                      :format "application/json",
                      :raw-format "application/json"},
   :muuntaja/response {:charset "utf-8",
                       :format "application/json",
                       :raw-format "application/json"},
   +:parameters {:body {:message "22"},
                 :path {:id 1},
                 :query {:name "2"}}}

2019-06-22 11:09:16,537 [XNIO-2 task-2] INFO  alk-wxapi.middleware.log-interceptor - 
================================ REQUEST START ================================
 request-id:8ddb3169-e72f-4b90-8811-d500c50d3057
 request-uri: /api/guestbooks/path/good-all-params/1
 request-method: :post
 request-query: {:name "2"}
 request-body: {:message "22"} 
--- Middleware ---

  {:body #<io.undertow.io.UndertowInputStream@39931c66>,
   :body-params {:message "22"},
   :character-encoding "ISO-8859-1",
   :content-length 21,
   :content-type "application/json",
   :context "",
   :cookies {"JSESSIONID" {:value "GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU"},
             "_ga" {:value "GA1.1.521496834.1555489511"},
             "_gid" {:value "GA1.1.947080805.1561170619"}},
   :flash nil,
   :form-params {},
   :handler-type :undertow,
   :headers {"accept" "application/json",
             "accept-encoding" "gzip, deflate, br",
             "accept-language" "zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7",
             "connection" "keep-alive",
             "content-length" "21",
             "content-type" "application/json",
             "cookie" "_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619",
             "host" "localhost:3000",
             "origin" "http://localhost:3000",
             "referer" "http://localhost:3000/api/api-docs/index.html",
             "user-agent" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"},
   :multipart-params {},
   :parameters {:body {:message "22"},
                :path {:id 1},
                :query {:name "2"}},
   :params {:name "2"},
   :path-info "/api/guestbooks/path/good-all-params/1",
   :path-params {:id "1"},
   :query-params {"name" "2"},
   :query-string "name=2",
   :remote-addr "0:0:0:0:0:0:0:1",
   :request-method :post,
   :scheme :http,
   :server-exchange #<io.undertow.server.HttpServerExchange@78f2e776 HttpServerExchange{ POST /api/guestbooks/path/good-all-params/1 request {Accept=[application/json], Accept-Language=[zh-CN,zh;q=0.9,zh-TW;q=0.8,en;q=0.7], Accept-Encoding=[gzip, deflate, br], Origin=[http://localhost:3000], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36], Connection=[keep-alive], Content-Length=[21], Content-Type=[application/json], Cookie=[_ga=GA1.1.521496834.1555489511; JSESSIONID=GpSiQENkmzM7qQwqWdYxjehYKvNKoEGMG6MIwqwU; _gid=GA1.1.947080805.1561170619], Referer=[http://localhost:3000/api/api-docs/index.html], Host=[localhost:3000]} response {Server=[undertow]}}>,
   :server-name "localhost",
   :server-port 3000,
   :session nil,
   :ssl-client-cert nil,
   :uri "/api/guestbooks/path/good-all-params/1",
   :muuntaja/request {:charset "utf-8",
                      :format "application/json",
                      :raw-format "application/json"},
   :muuntaja/response {:charset "utf-8",
                       :format "application/json",
                       :raw-format "application/json"}}

可以看到在reitit.ring.coercion/coerce-request中间件处理后request里增加了 :parameters { :body {:message "22"}, :path {:id 1}, :query {:name "2"}} 3种类型一致的map,这就是我们为什么推荐使用的原因。

handler里获取request自定义的对象:

那么,在上一步handle中加入到request中了一个current-user怎么获取和使用呢?其实,body-params,query-params这些也只是从request中获取到的而已,既然能从request中获取这些,那么request里的其他所有自然也能在handler中获取,看下面的例子:

["/reset/pwd"
    {:post {:summary    "修改密码"
            :parameters {:body (s/keys :req-un [::old-pwd ::new-pwd])}
            :handler    (fn [{{{:keys [old-pwd new-pwd]} :body} :parameters :as request}]
                          (let [current-id (-> request :current-user :user-id)
                                db-user (db/get-user-id
                                         {:user-id current-id})]
                            (if (check-old-pwd old-pwd (:password db-user))
                              (do (conman.core/with-transaction
                                    [*db*]
                                    (db/update-pwd! {:password  (d/sha-256 new-pwd)
                                                         :user-id current-id}))
                                  {:status 200
                                   :body   {:code    1
                                            :message "修改成功,请用新密码登录"}})
                              {:status 400
                               :body   {:code    0
                                        :message "密码错误,请输入正确的密码!"}})))}}]

:as request的意思是包含前面指定获取的参数的所有。

当然,如你所知,clojure确实足够灵活,取参方式也还有方式,比如

["/path/good-all-params/:id"
   {:post {:summary    "更多方式"
           :parameters {:path  {:id int?}
                        :query {:name string?}
                        :body  {:message string?}}
           :handler    (fn [{{data :body} :parameters
                             {{:keys [id]} :path}    :parameters]
                        (ok (format " body params: %s " data)))}}]


这里参数名称data可以定义成任何你想叫的名字。

Tags: clojure web