Static files with clojure and ring

I am creating a clojure / ring test project to find out how it works. I created an application that I call "junkapp" and it has really one handler

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

And also one wrap-resource call for static content

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

So then in my .clj project I have a link to lein-ring and also set: handler of my junkapp.core / app

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

when I run this with lein running, everything works as expected. Calling / returns "Hello World", and calling /test.html returns the contents of /public/test.html.

But then I tried to create it in a war file using

 lein ring uberwar junkapp.war 

and place it under the tomcat7 server webapps / dir. Now, when I go to any path under junkapp (so / junkapp /, / junkapp / foo, / junkapp / test.html), it always returns “Hello World”, and I cannot make it link to static content at all. In googling, I see that people just say they use compojure.route / resources, but as I study, I would like it to work this way and then add more libraries later. What's going on here?

+6
source share
2 answers

I think what is happening here is that there is code in wrap-resources here , in particular this line:

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

What happens is that when it is created as a war file, it does not understand that WEB-INF / classes / is the root of the path that it should use to serve static content. So, he is looking for public / test.html somewhere else (maybe the root .war?), And therefore this “or” is false, so he has to directly access the handler.

I am not sure about this because I am not quite sure that the internal work on how tomcat handles this internally ... that is, I do not know where it is looking for the base path.

+2
source

From my handler.clj (I use compojure and 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)) 

Now I don't know the details of how WARs should behave, but let's notice this war handler from 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 application example: https://github.com/bitemyapp/neubite/

Compojure (routing): https://github.com/weavejester/compojure

Bag of useful utilities collected after Noir: https://github.com/noir-clojure/lib-noir

+1
source

Source: https://habr.com/ru/post/948149/


All Articles