Question

I'm trying to build a simple web site using Clojure / Compojure and want to feed apply a servlet filter to the request / response (i.e. a standard javax.servlet.Filter instance).

e.g. if the current source code is:

(defroutes my-app
  (GET "/*"
    (html [:h1 "Hello Foo!!"]))
)

I would like to add a filter like this:

(defroutes my-app
  (GET "/*"
    (FILTER my-filter-name
      (html [:h1 "Hello Foo!!"])))
)

Where my-filter-name is some arbitrary instance of javax.servlet.Filter.

Any idea how to do this effectively and elegantly?

Was it helpful?

Solution

Ok I've now got this working! Thanks cgrand for the pointers in the right direction!

My solution involved creating proxies for a filtered servlet and a filter chain. Code below for anyone interested.....

(def pass-through-filter 
  (proxy [javax.servlet.Filter] []
    (doFilter
      [request response #^javax.servlet.FilterChain filterchain]
      (do
        (.doFilter filterchain request response)))))

(defn filter-chain 
  [#^javax.servlet.Servlet servlet]
  (proxy [javax.servlet.FilterChain] []
    (doFilter
      [request response]
      (.service servlet request response))))

(defn filtered-servlet 
  [#^javax.servlet.Filter servlet-filter handler]
  (let [#^javax.servlet.Servlet base-servlet (servlet handler)
        the-filter-chain (filter-chain base-servlet)]
    (proxy [javax.servlet.http.HttpServlet] []
      (service
        [request response] 
        (.doFilter servlet-filter request response the-filter-chain))
      (init
        [config] 
        (.init base-servlet config)))))

(defroutes my-app
  (GET "/*"
    (html 
      [:h1 "Hello Foo!!"]))
  (ANY "*"
    [404 "Page not found"]))

(run-server {:port 80}
  "/*" (filtered-servlet pass-through-filter my-app))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top