2010-05-10 12 views
6

Estoy intentando crear un sitio web simple usando Clojure/Compojure y quiero alimentar aplicar un filtro de servlet a la solicitud/respuesta (es decir, una instancia javax.servlet.Filter estándar) .Uso de javax.servlet.Filter con Compojure

p. Ej. si el código fuente actual es:

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

Me gustaría añadir un filtro de la siguiente manera:

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

Donde mi-filter-name es cierto caso arbitrario de javax.servlet.Filter.

¿Alguna idea de cómo hacerlo de manera efectiva y elegante?

+3

¿Desea aplicar el filtro a todas las rutas o solo algunas? En el primer caso, puede ser más fácil colocar el filtro sobre el Anillo/Compuesto, en el nivel del servlet. En el segundo caso, debe escribir (con reify o proxy) un adaptador que convierta un filtro en un middleware. – cgrand

+0

Gracias muy útil. Me gustaría hacer el segundo, pero no parece posible porque los parámetros de solicitud/respuesta que necesita el filtro no se pasan como parámetros al sistema de middleware. Estoy intentando el primero - ¡publicaré una respuesta si la hago funcionar! – mikera

+3

Para hacer lo segundo, también necesita crear objetos que implementen HttpServletRequest/Response en la parte superior de los mapas de solicitud/respuesta. O para usar la implementación existente (por ejemplo, http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/MockHttpServletRequest.html) pero creo que es más sencillo implementarlos con reify que lidiar con un objeto simulado con estado, como dice Rich Hickey "¡Esos objetos simulados, te están burlando!" – cgrand

Respuesta

8

Ok, ¡ahora lo tengo funcionando! Gracias cgrand por los indicadores en la dirección correcta!

Mi solución consistía en crear proxies para un servlet filtrado y una cadena de filtros. Código a continuación para cualquier persona interesada .....

(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)) 
+2

No necesita agregar su definición de filtro al archivo web.xml? – Chiron

Cuestiones relacionadas