设为首页 收藏本站
查看: 1039|回复: 0

[经验分享] Clojure Web 开发 (一)

[复制链接]

尚未签到

发表于 2017-2-28 10:29:36 | 显示全部楼层 |阅读模式
  使用Clojure做Web开发需要的工具链还是比较特殊的,本文主要描述一下其中牵涉到的框架。
  需要指出的是,Clojure可以把自己封装成jar包供java调用,因此最坏情况下还是可以用java servlet来调用Clojure的库的,但是这显然不是我想要达到的效果,因此本文的基本出发点是,核心语言用Clojure,需要调用java库的情况。
  首先要介绍的就是Ring    API文档
  Ring是一个Clojure Web程序库,有点类似与Java的servlet。为什么要用Ring呢?Wiki里面列了几个好处:


  • Write your application using Clojure functions and maps
  • Run your application in a auto-reloading development server
  • Compile your application into a Java servlet
  • Package your application into a Java war file
  • Take advantage of a large selection of pre-written middleware
  • Deploy your application in cloud environments like Amazon Elastic Beanstalk and Heroku
  事实上,Ring是大部分Clojure的Web Framework的基础。包括了:Compojure、Moustache和Noir。
  真正在开始用Ring之前,首先要介绍的就是Leiningen。这个玩意也是个挺牛b的东西,而且作者也比较有意思,用户问答文档里面全面嘲笑了Ant和Maven,虽然Leiningen就是基于他们的。按照我现在的理解,基本上,用这个玩意,只要你指定好了依赖关系,它就会自动下载对应的库,并且放在正确的地方,然后还可以编译你的项目,执行你的项目。下面我们用的所有库都是用Leiningen实现的。
  -------------
  RING
  使用leiningen创建一个项目:



lein new hello-world
cd hello-world
  紧接着就要修改project.clj,指定依赖关系。



(defproject hello-world "1.0.0-SNAPSHOT"
  :description "FIXME: write"
  :dependencies [[org.clojure/clojure "1.2.0"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [ring/ring-core "0.3.4"]
                 [ring/ring-jetty-adapter "0.3.4"]])
  然后调用deps来告诉leiningen下载需要的数据:



lein deps
  接着修改项目文件夹src目录下的core.clj文件如下:



(ns hello-world.core)
(defn handler [request]
  {:status 200
   :headers {"Content-Type" "text/html"}
   :body "Hello World"})
  之后便可以调用



lein repl
  调用出REPL,接着就可以在命令行中启动服务器



=> (use 'ring.adapter.jetty)
=> (use 'hello-world.core)
=> (run-jetty handler {:port 3000})
  在Ring的抽象中,一个web程序分为4个部分,Handler、Request、Response、MiddleWare
  其中Handler即为定义web程序的函数,该函数只有一个参数:一个代表了Http请求的Map,最后返回一个代表HTTP返回值的map。比如:



(defn what-is-my-ip [request]
  {:status 200
   :headers {"Content-Type" "text/plain"}
   :body (:remote-addr request)})
  Request也就是http请求也是一个Map,下面主要描述了其自带的key的情况。在ring中,可以使用middleware添加用户自定义的key:


  • :server-port The port on which the request is being handled.
  • :server-name The resolved server name, or the server IP address.
  • :remote-addr The IP address of the client or the last proxy that sent the request.
  • :uri The request URI (the full path after the domain name).
  • :query-string The query string, if present.
  • :scheme The transport protocol, either :http or :https.
  • :request-method The HTTP request method, which is one of :get, :head, :options, :put, :post, or :delete.
  • :content-type The MIME type of the request body, if known.
  • :content-length The number of bytes in the request body, if known.
  • :character-encoding The name of the character encoding used in the request body, if known.
  • :headers A Clojure map of lowercase header name strings to corresponding header value strings.
  • :body An InputStream for the request body, if present.


Response与Reqeust类似,包含了三个Key:



  • :status The HTTP status code, such as 200, 302, 404 etc.
  • :headers A Clojure map of HTTP header names to header values. These values may either be strings, in which case one name/value header will be sent in the HTTP response, or a collection of strings, in which case a name/value header will be sent for each value.
  • :body A representation of the response body, if a response body is appropriate for the response's status code. The body can be one of four types:

    • String The body is sent directly to the client.
    • ISeq Each element of the seq is sent to the client as a string.
    • File The contents of the referenced file is sent to the client.
    • InputStream The contents of the stream is sent to the file. When the stream is exhausted, the stream is closed.



Middleware是一个高阶函数,该函数第一个参数是一个handler,给该函数做一些处理之后,返回一个新的handler函数。比如:




(defn wrap-content-type [handler content-type]
  (fn [request]
    (let [response (handler request)]
      (assoc-in response [:headers "Content-Type"] content-type))))

而在Ring中,通常使用宏:-> 来将多个middleware串联起来,形成:Ring?



Ring中如何产生Response。



Ring提供了ring.util.response来帮助生成一下response。但事实上,我们通常会使用专门的render库来生成返回数据,这里先不表,只列出一下Ring提供的Response函数 (API文档):




(response "Hello World")
(-> (response "Hello World")
    (content-type "text/plain"))
(redirect "http://example.com")
(file-response "readme.html" {:root "public"})
(resource-response "readme.html" {:root "public"})
  ring也支持cookie和session。最重要的是Ring支持交互式的开发,这个也是Lisp的强项。
  进行交互式开发的三种方法,我们这里主要引述一下使用lein-ring插件的方法:
  1,首先在project.clj文件中指明:



:dev-dependencies [[lein-ring "0.4.5"]]
  2, 运行lein deps,下载对应的库
  3,在Project.clj文件最后添加:



:ring {:handler your-app.core/handler}))
  4,调用下面命令启动服务器:



lein ring server
  5,该服务器会自动重新加载src中任何修改过的文件。

介绍了Ring之后,我们需要了解,大部分情况下我们不需要在Ring之上写web程序,因为已经有人帮我们弄了一些框架,这些框架能够极大的简化开发流程,这些框架中比较流行的包括:


  • Compojure: A concise DSL to generate Ring handler functions
  • Moustache: A micro DSL to wire Ring handlers and middlewares
  • fjord: A minimal Ring app framework
  • clocks: Clojure Web DSL build on top of compojure, ring and scripture
  • Ringfinger: RESTful resources with multiple outputs (HTML, XML, JSON), database and email abstraction, pre-made authorization system (form-based + HTTP Basic), security middleware, etc.
  • Noir: A micro-framework that allows you to rapidly develop websites in Clojure.




下一篇我们将主要介绍Compojure以及render lib。  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348311-1-1.html 上篇帖子: [使用心得]maven2之m2eclipse使用手册之六使用Maven2插件创建一个简单的SSH2项目之glassfish篇(一) 下篇帖子: tcp链接的几种状态&tcpdump抓包
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表