2010-05-10 13 views
6

Ich versuche, eine einfache Website mit Clojure/Compojure zu erstellen und feed einen Servlet-Filter auf die Anfrage/Antwort anwenden (dh eine Standard-javax.servlet.Filter-Instanz) .Verwendung eines javax.servlet.Filter mit Compojure

z.B. wenn der aktuelle Quellcode ist:

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

würde Ich mag einen Filter wie folgt hinzuzufügen:

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

Wo ist mein-Filter-Name einige beliebige Instanz von javax.servlet.Filter ist.

Irgendeine Idee, wie man das effektiv und elegant macht?

+3

Möchten Sie Ihren Filter auf alle Routen anwenden oder nur einige? Im ersten Fall kann es einfacher sein, den Filter oberhalb von Ring/Compojure auf der Servlet-Ebene anzuordnen. Im zweiten Fall müssen Sie (mit retify oder proxy) einen Adapter schreiben, der einen Filter in eine Middleware verwandelt. – cgrand

+0

Danke sehr hilfreich. Ich möchte das zweite tun, aber es scheint nicht möglich zu sein, da die Request/Response-Parameter, die der Filter benötigt, nicht als Parameter an das Middleware-System übergeben werden. Ich versuche das erste - werde eine Antwort posten, wenn ich es zur Arbeit bekomme! – mikera

+3

Um die zweite Aufgabe auszuführen, müssen Sie auch Objekte erstellen, die HttpServletRequest/Response über den Anforderungs-/Antwortkarten implementieren. Oder um bestehende Implementierungen zu verwenden (zB http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/MockHttpServletRequest.html), aber ich denke, es ist einfacher, sie mit retify als zu implementieren beschäftigen Sie sich mit einem Stateful Mock-Objekt - wie Rich Hickey sagt "Diese Mock-Objekte, sie verspotten Sie"! – cgrand

Antwort

8

Ok Ich habe jetzt funktioniert das! Vielen Dank für die Hinweise in die richtige Richtung!

Meine Lösung beinhaltete die Erstellung von Proxys für ein gefiltertes Servlet und eine Filterkette. Code weiter unten für alle Interessierten .....

(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

Sie müssen Ihre Filterdefinition nicht zur web.xml-Datei hinzufügen? – Chiron