Clojure和Ring中的静态文件

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设置为my junkapp.core/app。

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

当我使用“lein run”运行时,一切都按预期工作。对“/”的调用会返回“Hello World”,对“/test.html”的调用会返回resources/public/test.html的内容。
但是,当我尝试将其构建为war文件时……
lein ring uberwar junkapp.war

将它放在 Tomcat7 服务器的 webapps/ 目录下。现在,当我访问 junkapp 下的任何路径 (如 /junkapp/, /junkapp/foo, /junkapp/test.html),它总是返回 "Hello World",而我似乎无法让它引用静态内容。在谷歌搜索时,我看到有人只是说要使用 compojure.route/resources,但由于我正在学习,我希望它能像这样工作,然后再添加更多库。这里发生了什么事?

你已经验证了静态文件是否包含在WAR中吗? - Alex
是的,具体的测试文件在这里:webapps/junkapp/WEB-INF/classes/public/test.html - MichaelB
2个回答

2

我认为这里发生的情况是,在wrap-resources 这里有一些代码,具体来说是这一行:

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

当以war文件的形式构建时,它不理解WEB-INF/classes/是用于提供静态内容的根路径。因此,它正在寻找public/test.html在其他地方(也许是.war的根目录?),所以这个"or"是错误的,因此它直接调用处理程序。

我不确定如何修复这个问题,因为我不完全了解Tomcat内部处理的工作原理……也就是说,我不知道它在哪里查找基本路径。


这与ServletConext有关。请参阅此邮件列表线程:https://groups.google.com/forum/#!topic/clojure-web-dev/dg_lVfi1y-w - noahlz
是的,那基本上也说了我所说的... WEB-INF/classes 应该是类路径的基础。因此它应该能够在其下找到 public/test.html。出于某种原因它没有找到。 - MichaelB
这可能有额外的提示:https://github.com/weavejester/compojure-example/issues/1#issuecomment-1538577 - 如果有解决方案,我很感兴趣。 - noahlz

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的war-handler:

(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


OP 表示他想使用裸机环境,而不是其他任何框架。 - noahlz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接