I thought I give the current compojure+ring another look to see where
things stand. I'm setting up
a servlet because I want to produce a war file so that it can be
deployed to tomcat etc.
So I wrote something extremely basic.
(ns mywebapp.firstservlet
(:use [ring.util.servlet :only (defservice)])
(:use compojure.core)
(:gen-class
:extends javax.servlet.http.HttpServlet))
(defroutes app
(GET "/working" [] "it worked")
(GET "/sayhi" [] "say hi")
(GET "/" [] "top level"))
(defservice app)
I also created a web.xml file to map url-pattern / to it.
when I deploy it to jetty, going to any url gives me a
java.lang.NullPointerException: Handler returned nil
at ring.util.servlet$make_service_method$fn__78.invoke(servlet.clj:118)
if I change the defroute above to
(defroutes app
(GET "/working" [] "it worked")
(GET "/sayhi" [] "say hi")
(GET "/*" [] "top level"))
it works, but no matter what I do, it always says "top level". I
thought the route are
matched in the order it was defined?
any input on what I'm missing is appreciated.
Thanks,
--
Omnem crede diem tibi diluxisse supremum.
In web.xml, you need to bind the url pattern "/*", not "/". Without the wildcard, it will only match the root.
- James
--
You received this message because you are subscribed to the Google Groups "Compojure" group.
To post to this group, send email to comp...@googlegroups.com.
To unsubscribe from this group, send email to compojure+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/compojure?hl=en.
I thought I give the current compojure+ring another look to see where
things stand. I'm setting up
a servlet because I want to produce a war file so that it can be
deployed to tomcat etc.
<web-app>
<servlet>
<servlet-name>firstservlet</servlet-name>
<servlet-class>mywebapp.firstservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>firstservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
still get the same result as I stated before. using the web.xml from above.
redoing the defroute with a catch all, I have
(ns mywebapp.firstservlet
(:use [ring.util.servlet :only (defservice)])
(:use compojure.core)
(:gen-class
:extends javax.servlet.http.HttpServlet))
(defroutes app
(GET "/working" [] "it worked")
(GET "/sayhi" [] "say hi")
(GET "/" [] "top level")
(ANY "/*" [] "not found"))
(defservice app)
it always returns "not found", and never match any of the other url
pattern. I checked
the defroutes syntax against docs/examples I found on the web several times.
It looks right to me. But for some reason, it's always matching the last one.
I'm using gradle and the clojure plugin clojuresque, as well as the jetty
and war plugin for gradle.
so I can just do gradle war to produce the war file.
I can do gradle jettyRun to run jetty etc.
> --
> You received this message because you are subscribed to the Google Groups
> "Compojure" group.
> To post to this group, send email to comp...@googlegroups.com.
> To unsubscribe from this group, send email to
> compojure+...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/compojure?hl=en.
>
--
(ANY "*" {uri :uri} uri)
Compojure matches on the :uri key of the request, and this route echos
the URI in the response. This might tell you why the URI isn't
matching in this case.
- James
(defroutes app
(GET "/webexample/working" [] "it worked")
(GET "/webexample/sayhi" [] "say hi")
(GET "/webexample/" [] "top level")
(ANY "/*" [] "not found"))
because my working directory is webexample, and gradle
package up the war to webexample.war by convention,
thus deploying to to jetty as /webexample in the webexample
context
I didn't realize compojure route mapping takes web context into
account.
James, is there a way to change this behavior? Because
unless I deploy the war to ROOT context, it would never match.
and since context changes depends on what you name the war file.
it'd be nice if this can be configurable somehow?
> --
> You received this message because you are subscribed to the Google Groups "Compojure" group.
> To post to this group, send email to comp...@googlegroups.com.
> To unsubscribe from this group, send email to compojure+...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/compojure?hl=en.
>
>
--
Yes, you can use some middleware that alters the :uri key:
(defn wrap-context [handler context]
(fn [{uri :uri :as request}]
(if (.startsWith uri context)
(handler (assoc request :uri (.substring uri (.length context)))))))
I'm thinking about adding a function like this into Ring. I'm also
going to add an option or some middleware to defservice and defservlet
that would make servlets take the context into account.
- James
On Mon, Jul 26, 2010 at 5:31 AM, Saul Hazledine <sha...@gmail.com> wrote:
...
> When on a live server I always run Jetty behind an Nginx proxy and use
> Nginx to cache static content and to translate paths. This way a
> servlet running in Jetty is always be on the same absolute path. Any
> Compojure based servlet can share Jetty with lots of other servlets
> (written in Java or whatever) and Nginx does the path conversion. Its
> also much easier to change an Nginx configuration file than to edit a
> web.xml and create a new war file if you do want to change a path.
> With Nginx you also get control over virtual hosts etc.
>
> e.g
> URI / -> Nginx proxies to http://localhost:8080/myservlet/ -> Jetty
> gets /myservlet/
> URI /hi -> Nginx proxies to http://localhost:8080/myservlet/hi ->
> Jetty gets /myservlet/hi
> URI /static/hi.css -> Nginx caches http://localhost:8080/myservlet/hi/static/hi.css
>
--
Thanks
On Mon, Jul 26, 2010 at 5:43 AM, James Reeves <jre...@weavejester.com> wrote:
> (defn wrap-context [handler context]
> (fn [{uri :uri :as request}]
> (if (.startsWith uri context)
> (handler (assoc request :uri (.substring uri (.length context)))))))
--
A Ring request translated from a servlet request will have, I believe,
a :servlet-request key that references a HttpServletRequest object.
You can probably use this to pull out the truncated path (getPathInfo,
possibly?). You can then put this path into :uri, and move the
existing URI value to a :full-uri key.
I'm planning to create middleware like this anyway, so if you happen
to do this before me, I'll be happy to merge it into Ring core.
- James