Understanding Clojure Ring Middleware

本文介绍了使用Clojure进行Web开发的基本方法,包括如何创建一个简单的HTTP handler来响应客户端请求,以及如何使用Middleware来增强请求处理流程。通过具体示例展示了如何修改响应内容和解析请求参数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们先创建一个handler

(ns middleware-example
  (:use ring.adapter.jetty
        ring.middleware.params))

(defn handler [request]
    {:headers {}
     :status 200
     :body (str "Hello word!" )})

(def app
  handler)

;; Start the server if it hasn't already been started
(defonce server (ring.adapter.jetty/run-jetty #'app {:port 7071 :join? false}))

我们看到,handler会接收一个request参数,并返回一个hash-map,hash-map包括headers、status和body,这个hash-map就是一个response。
党我们访问 http://localhost:7071/ ,就会看到 Hello word!

用middleware处理response


(defn shout
  [handler]
  (fn [request]
    (let [response (handler request)]
      (update-in response [:body] clojure.string/upper-case)))) ;; 将response中的body转换成大写

(def app
  (-> handler
    shout))

当我们刷新页面的时候,结果就变成了 HELLO WORD!
这个例子说明,我们可以通过middleware改变response。

用middleware处理request

我们可以用middle更好的解析、处理request,请看下面的例子

(ns middleware-example
  (:use ring.adapter.jetty
        ring.middleware.params))

(defn print-query-params [handler]
  (fn [request]
    (println "In print-query-params, the params is:" (:query-params request))
    (handler request)))

(defn handler [request]
  (println "In handler, the params is:" (:query-params request))
  (let [name ((:query-params request) "name")]
    {:headers {}
     :status 200
     :body (str "Hello " name "!")}))

(def app
  (-> handler
      wrap-params
      print-query-params))

;; Start the server if it hasn't already been started
(defonce server (ring.adapter.jetty/run-jetty #'app {:port 7071 :join? false}))

访问 http://localhost:7071?name=mike 后,在console里我们将看到

In print-query-params, the params is: nil
In handler, the params is: {name mike}

这段代码可以说明,params是被wrap-params所解析出来的,request在创给wrap-paramshandler前,先被传给了print-query-params

(在浏览器内,我们实际上会看到两次输出,是因为浏览器在请求url的时候,还请求了favoicon,chrome每次刷新都是两个请求,而safari只有第一次请求了favoicon,之后刷新都没有再次请求)

Middleware

首先,我们将handler这个参数传给middleware,这个middleware会返回一个方法,
这个方法会接收一个request参数,我们可以在这个方法里生成新的request,并把这个request传给handler(handler new-request),得到返回后,我们又可以对response进行操作。

通过app的定义(-> handler wrap-params print-query-params),我们知道,middleware就像洋葱皮一样,一层层包裹handler。

最后面的包裹在最外层,request一层层通过middleware,每一层都可以对request进行操作,最后handler 会根据最终的request生成response,然后response又一层层传出middleware,每一层middleware有有机会对生成的response做处理。

就像下图一样(注意,后面的middleware,处于最外层)。
图片描述

其他框架的中间件

rack也是使用一样的模型处理中间件。rack使用use方法注册middleware,并将注册的middleware放入@use这个实例变量里。
rack有一个to_app的方法,在这个方法内@use.reverse.inject(app) { |a,e| e[a] },把最先注册的middleware放在最外层,并包裹好。

ring、rack、koa的middleware都是使用洋葱模型,但express的middleware却不一样,middleware只是一层一层传下去的,比如要记录请求时间,就需要写两个中间件。

var app = express()

app.use(function (req, res, next) {
  console.log('Time:', Date.now())
  next()
})

小结

Middleware可以用来对response和request进行处理(比如解析params),也可以中断执行(比如过滤ip)等。
但需要注意middleware的顺序,最后的middleware被放在了最外层。最外层,最先处理request,最后处理response。

参考

https://codenoble.com/blog/un...
https://expressjs.com/en/guid...
http://liujiacai.net/blog/201...

内容概要:该论文聚焦于T2WI核磁共振图像超分辨率问题,提出了一种利用T1WI模态作为辅助信息的跨模态解决方案。其主要贡献包括:提出基于高频信息约束的网络框架,通过主干特征提取分支和高频结构先验建模分支结合Transformer模块和注意力机制有效重建高频细节;设计渐进式特征匹配融合框架,采用多阶段相似特征匹配算法提高匹配鲁棒性;引入模型量化技术降低推理资源需求。实验结果表明,该方法不仅提高了超分辨率性能,还保持了图像质量。 适合人群:从事医学图像处理、计算机视觉领域的研究人员和工程师,尤其是对核磁共振图像超分辨率感兴趣的学者和技术开发者。 使用场景及目标:①适用于需要提升T2WI核磁共振图像分辨率的应用场景;②目标是通过跨模态信息融合提高图像质量,解决传统单模态方法难以克服的高频细节丢失问题;③为临床诊断提供更高质量的影像资料,帮助医生更准确地识别病灶。 其他说明:论文不仅提供了详细的网络架构设计与实现代码,还深入探讨了跨模态噪声的本质、高频信息约束的实现方式以及渐进式特征匹配的具体过程。此外,作者还对模型进行了量化处理,使得该方法可以在资源受限环境下高效运行。阅读时应重点关注论文中提到的技术创新点及其背后的原理,理解如何通过跨模态信息融合提升图像重建效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值