Compojure/教程和技巧
此页面可能需要更新以反映当前知识。 您可以 帮助更新它,讨论进度,或 请求帮助。 |
这是一个使用 Compojure Web 框架的示例集合。
Compojure 默认情况下不提供静态文件,也不会在没有匹配路由时自动处理 404 错误。Compojure 不会对你想做什么做任何假设;你必须明确说明。
为了提供静态文件,你通常需要添加两个处理程序。一个用于服务文件,另一个用于在第一个处理程序失败时引发 404 错误
(compojure.route/files "public") (compojure.route/not-found "Not found.")
如 https://weavejester.github.io/compojure/compojure.route.html 文档所述
使用命名空间和 :require 映射,例如
(ns coolproject.handler (:require [compojure.core :refer :all] [compojure.route :as route]))
然后你对 compojure.route 的调用可以简化为
(route/files "public")
它将自动在你的 src/resources/public 目录中查找静态文件(.css、图像等)。
两个 Compojure Servlet 相比一个 Servlet 的唯一优势是功能划分清晰。例如,如果你的网站有一个与公共网站截然不同的管理员界面,你可能希望创建两个 Servlet;一个用于公共访问,另一个用于管理员控制面板。
另一种需要多个 Servlet 的情况是,你的一个 Servlet 是用 Java 编写的。例如,Jetty 包含一个用于处理 Cometd 请求的 Servlet,ContinuationCometdServlet。在我使用 Compojure 构建的应用程序中,我将此 Servlet 绑定到 "/_cometd/*",并将我的主要 Compojure Servlet 绑定到 "/*".
但对于正常使用,我倾向于将所有内容都放在一个 Servlet 中。如果你看一下像 Ruby on Rails 这样的框架,所有的路由信息都保存在一个文件中。Compojure Servlet 具有类似的用途,它们充当通往构成你的网站的 Clojure 函数的网关。实际的 Servlet 本身应该包含很少的逻辑,它应该看起来几乎像整个网站的高级概述。
以下代码定义了 input-date-field 函数,它可以像其他任何输入辅助函数一样使用。该表单将以 Unix 时间格式返回日期。参数是:表单字段的名称、当前值以及年份选择器的起始年和结束年。
;;; Date form field (def *date-class* (.getClass (new java.util.Date (long 0)))) (def *date-format* (new java.text.SimpleDateFormat "yyyy-MM-dd")) (defn parseLong [s] (try (Long/parseLong (str s)) (catch java.lang.Exception e 0))) (defn get-date-from-anything [value] "Returns a Date object. Accepts a Date, number or String." (cond (nil? value) (new java.util.Date (long 0)) (instance? *date-class* value) value (number? value) (new java.util.Date (* 1000 (long value))) true (new java.util.Date (* 1000 (long (parseLong (str value))))))) (import '(java.util Calendar)) (def monthNames ["January" "February" "March" "April" "May" "June" "July" "August" "September" "October" "November" "December"]) (defn input-date-field "Creates a form element to input a date" [name value fromYear toYear] (let [calendar (Calendar/getInstance) name (.replaceAll (str name) ":" "")] (.setTime calendar (get-date-from-anything value)) (html (str "<script> function changed_date_" name "() { function $(id) { return document.getElementById(id); } var date = new Date(parseInt($('year_" name "').value), parseInt($('month_" name "').value), parseInt($('day_" name "').value)); $('" name "').value = date.getTime() / 1000; //alert('c=:' + $('" name "').value); } </script>") [:input {:type 'hidden :name name :id name :value value}] [:input {:type 'text :id (str "day_" name) :value (.get calendar Calendar/DAY_OF_MONTH) :size 1 :onchange (str "changed_date_" name "();")}] " " [:select {:id (str "month_" name) :onchange (str "changed_date_" name "();")} (reduce #(str % (html [:option {:value %2 :selected (if (= %2 (.get calendar Calendar/MONTH)) "true" nil)} (nth monthNames %2)])) "" (range 12))] " " [:select {:id (str "year_" name) :onchange (str "changed_date_" name "();")} (reduce #(str % (html [:option {:value (+ fromYear %2)} (+ fromYear %2)])) "" (range (- (inc toYear) fromYear)))] " " )))