Clojure Web 开发从零开始(四):返回 JSON 与表单处理

在前一篇文章里,我们用 Compojure 建立了基本路由,并结合 Ring 中间件
这次我们继续扩展,增加 返回 JSON 数据表单提交处理,让应用更接近实际 Web API。


1. 添加 JSON 库

我们需要一个 JSON 解析/生成库。这里选用 cheshire

project.clj 中加入:

[cheshire "5.10.0"]

执行:

lein deps

2. 返回 JSON 响应

src/clj_httpbin/core.clj

(ns clj-httpbin.core
  (:require [org.httpkit.server :as http]
            [compojure.core :refer :all]
            [compojure.route :as route]
            [cheshire.core :as json]
            [ring.middleware.defaults :refer [wrap-defaults api-defaults]])
  (:gen-class))

(defroutes routes
  (GET "/" [] "<h1>Hello, World!</h1>")

  ;; JSON API
  (GET "/api/ping" []
    {:status 200
     :headers {"Content-Type" "application/json"}
     :body (json/generate-string {:message "pong" :time (System/currentTimeMillis)})})

  (route/not-found "Page not found"))

(def app
  ;; 使用 api-defaults,而不是 site-defaults
  (wrap-defaults routes api-defaults))

(defn -main []
  (println "Starting server on port 8080 ...")
  (http/run-server app {:port 8080}))

3. 处理表单提交

新增一个 POST /api/echo 路由,用于接收表单数据或 JSON:

(POST "/api/echo" {body :body params :params}
  {:status 200
   :headers {"Content-Type" "application/json"}
   :body (json/generate-string {:received (or params body)})})

4. 测试

启动应用:

lein run

测试 JSON API:

curl http://localhost:8080/api/ping

输出:

{"message":"pong","time":1694375623456}

测试表单提交:

curl -X POST -d "name=Lei&lang=clojure" http://localhost:8080/api/echo

输出:

{"received":{"name":"Lei","lang":"clojure"}}

也可以发送 JSON:

curl -X POST -H "Content-Type: application/json" -d '{"foo":"bar"}' http://localhost:8080/api/echo

输出:

{"received":{"foo":"bar"}}

小结

这一篇我们实现了:

  • 使用 cheshire 生成 JSON 响应
  • 定义 POST 路由 接收表单与 JSON 数据
  • 使用 api-defaults 提供更轻量的中间件