Web应用

有很多Clojure类库可以帮助我们创建web应用。现在比较流行使用Chris Granger写的 Noir 。另外一个简单的,基于MVC的框架, 使用Christophe Grand写的? Enlive 来做页面的template, 是Sean Corfield写的 Framework One 。另一个流行的选择是James Reeves写的Compojure,你可以在这里下载: http://github.com/weavejester/compojure/tree/master 。所有这些框架都是基于Mark McGranahan写的 Ring (James Reeves同学现在在维护). 我们以Compojure为例子来稍微介绍一下web应用开发。最新的版本可以通过git来获取:

git clone git://github.com/weavejester/compojure.git

这个命令会在当前目录创建一个叫做 compojure 的目录. 另外你还需要从 http://cloud.github.com/downloads/weavejester/compojure/deps.zip 下载所有依赖的JAR包,把 deps.zip 下载之后解压在 compojure 目录里面的 deps 子目录里面:

要获取 compojure.jar , 在compojure里面运行 ant 命令。

要获取 Compojure的更新, 切换到 compojure 目录下面执行下面的命令:

git pull
ant clean deps jar

所有的 deps 目录里面的jar包都必须包含在classpath里面。一个方法是修改我们的 clj 脚本,然后用这个脚本来运行web应用. 把 " -cp $CP " 添加到 java 命令后面去 执行 clojure.main添加下面这些行到脚本里面去,以把那些jar包包含在 CP 里面。

# Set CP to a path list that contains clojure.jar
# and possibly some Clojure contrib JAR files.
COMPOJURE_DIR=<em>path-to-compojure-dir</em>
COMPOJURE_JAR=$COMPOJURE_DIR/compojure.jar
CP=$CP:$COMPOJURE_JAR
for file in $COMPOJURE_DIR/deps/*.jar
do
  CP=$CP:$file
done

下面是他一个简单的 Compojure web应用:

Compojure input page Compojure output page

(ns com.ociweb.hello
  (:use compojure))

(def host "localhost")
(def port 8080)
(def in-path "/hello")
(def out-path "/hello-out")

(defn html-doc
  "generates well-formed HTML for a given title and body content"
  [title & body]
  (html
    (doctype :html4)
    [:html
      [:head [:title title]]
      [:body body]]))

; Creates HTML for input form.
(def hello-in
  (html-doc "Hello In"
    (form-to [:post out-path]
      "Name: "
      (text-field {:size 10} :name "World")
      [:br]
      (reset-button "Reset")
      (submit-button "Greet"))))

; Creates HTML for result message.
(defn hello-out [name]
  (html-doc "Hello Out"
    [:h1 "Hello, " name "!"]))

(defroutes hello-service
  ; The following three lines map HTTP methods
  ; and URL patterns to response HTML.
  (GET in-path hello-in)
  (POST out-path (hello-out (params :name)))
  (ANY "*" (page-not-found))) ; displays ./public/404.html by default

(println (str "browse http://" host ":" port in-path))
; -> browse http://localhost:8080/hello
(run-server {:port port} "/*" (servl