8

我正在构建一个测试 clojure/ring 项目来了解它是如何工作的。我创建了一个名为“junkapp”的应用程序,它确实有一个处理程序

(defn handler [request]
  {:status 200
  :headers {"Content-type" "text/html"}
  :body "Hello World"})

还有一个调用 wrap-resource 来获取静态内容

(def app
  (wrap-resource handler "public"))

那么在我的 project.clj 中,我引用了 lein-ring 并将 :handler 设置为我的 junkapp.core/app

:plugins [[lein-ring "0.8.5"]]
:ring {:handler junkapp.core/app}

当我用 lein run 运行它时,一切都按预期工作。对 / 的调用返回“Hello World”,对 /test.html 的调用返回 resources/public/test.html 的内容。

但后来我尝试将它构建成一个战争文件

lein ring uberwar junkapp.war

并将其放在tomcat7 服务器的webapps/ 目录下。现在,当我转到 junkapp 下的任何路径(例如 /junkapp/、/junkapp/foo、/junkapp/test.html)时,它总是返回“Hello World”,我似乎根本无法让它引用静态内容。在谷歌搜索中,我看到人们只是说要使用 compojure.route/resources 但随着我的学习,我希望它像这样工作,然后再添加更多库。这里发生了什么?

4

2 回答 2

2

我认为这里发生的事情是 wrap-resources here中有一些代码,特别是这一行:

(or ((head/wrap-head #(resource-request % root-path)) request)
  (handler request))))

发生的情况是,当构建为 war 文件时,它不理解 WEB-INF/classes/ 是它应该用来提供静态内容的路径的根。所以它在其他地方寻找 public/test.html(可能是 .war 的根?),所以这个“或”是错误的,所以它直接调用处理程序。

我不确定是否可以解决此问题,因为我不完全确定 tomcat 如何在内部处理此问题的内部工作......也就是说,我不知道它在哪里寻找基本路径。

于 2013-06-26T19:51:23.813 回答
1

从我的 handler.clj (我正在使用 compojure 和 lib-noir)

; defroutes and route/* being from Compojure
(defroutes app-routes
  (route/resources "/")
  (route/not-found "Not Found"))

(def all-routes [admin-routes home-routes blog-routes app-routes])
(def app (-> (apply routes all-routes)
; etc. etc.
(def war-handler (middleware/war-handler app))

现在我不知道 WAR 应该如何表现的细节,但让我们注意 lib-noir 中的这个战争处理程序:

(defn war-handler
  "wraps the app-handler in middleware needed for WAR deployment:
  - wrap-resource
  - wrap-file-info
  - wrap-base-url"
  [app-handler]
  (-> app-handler
      (wrap-resource "public")
      (wrap-file-info)
      (wrap-base-url)))

示例应用程序 CMS:https ://github.com/bitemyapp/neubite/

Compojure(路由):https ://github.com/weavejester/compojure

在 Noir 之后收获的有用实用程序包:https ://github.com/noir-clojure/lib-noir

于 2013-06-27T04:08:06.647 回答