2013-06-26 1 views
6

Я создаю тестовый проект clojure/ring, чтобы узнать, как он работает. Я создал приложение я называю «junkapp», и это действительно один обработчикСтатические файлы с clojure и ring

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

, а также один вызов обернуть-ресурс для статического контента

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

Итак, в моем project.clj у меня есть ссылка на LEIN-кольцо, а также установить: обработчик моей junkapp.core/приложение

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

, когда я запускаю это с LEIN перспективе, все работает, как ожидалось. Вызов/возвращает «Hello World», а вызов /test.html возвращает содержимое ресурсов/public/test.html.

Но тогда я пытался построить его в военный файл с

lein ring uberwar junkapp.war 

и поставить его под WebApps/реж сервера tomcat7. Теперь, когда я перехожу на любой путь под junkapp (so/junkapp /,/junkapp/foo, /junkapp/test.html), он всегда возвращает «Hello World», и я не могу заставить его ссылаться на статический контент вообще. В googling я вижу, что люди просто говорят, что используют compojure.route/resources, но по мере того, как я учусь, я бы хотел, чтобы он работал так, а затем добавлял больше библиотек позже. Что тут происходит?

+0

Вы подтвердили, что статические файлы включены в WAR? – Alex

+0

Да, тестовый вариант здесь конкретно: webapps/junkapp/WEB-INF/classes/public/test.html – MichaelB

ответ

2

Я думаю, что здесь происходит, что есть некоторый код в поствызывных ресурсах here, а именно эта линия:

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

Что происходит, что при встраивании в качестве военного файла, он не понимает, что WEB- INF/classes/является корнем пути, который он должен использовать для обслуживания статического содержимого. Таким образом, он ищет public/test.html где-то еще (возможно, корень .war?), И поэтому это «или» является ложным, поэтому ему приходится напрямую обращаться к обработчику.

Я не уверен в этом, так как я не совсем уверен, что внутренняя работа над тем, как tomcat обрабатывает это внутренне ... то есть я не знаю, где он ищет базовый путь.

+0

Это как-то связано с ServletConext. См. Этот список рассылки: https://groups.google.com/forum/#!topic/clojure-web-dev/dg_lVfi1y-w – noahlz

+0

Да, это в основном говорит то, что я сказал ... что WEB-INF/classes должен быть базой класса. Поэтому он должен иметь возможность находить public/test.html под ним. По какой-то причине это не так. – MichaelB

+0

У этого могут быть дополнительные подсказки: https://github.com/weavejester/compojure-example/issues/1#issuecomment-1538577 - заинтересованы в разрешении, если таковые имеются. – noahlz

1

С моей handler.clj (я использую compojure и Lib-нуар)

; 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)) 

Теперь я не знаю, сведение о том, как Войны должны вести себя, но позволяет примечанию этой войны обработчик от Lib-нуар:

(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

+0

OP заявила, что хочет использовать кольцо с голыми костями, а не любые другие рамки. – noahlz