2010-05-10 3 views
6

Clojure/Compojure를 사용하여 간단한 웹 사이트를 만들고 요청/응답에 서블릿 필터를 적용하려고합니다 (예 : 표준 javax.servlet.Filter 인스턴스) .Compojure로 javax.servlet.Filter 사용하기

현재 소스 코드 인 경우 :

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

나는이 같은 필터를 추가하고 싶습니다 :

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

을 내 필터 이름은 javax.servlet.Filter의 어떤 임의의 인스턴스입니다.

어떻게 효율적이고 우아하게 만들 수 있습니까?

+3

필터를 모든 경로 또는 일부에만 적용 하시겠습니까? 첫 번째 경우 서블릿 레벨에서 필터를 Ring/Compojure 위에 두는 것이 더 쉬울 수 있습니다. 두 번째 경우에는 필터를 미들웨어로 바꾸는 어댑터 (reify 또는 proxy로 작성)가 필요합니다. – cgrand

+0

감사합니다. 매우 도움이됩니다. 두 번째 작업을하고 싶습니다만 필터가 필요로하는 요청/응답 매개 변수가 매개 변수로 미들웨어 시스템에 전달되지 않았기 때문에 가능하지 않습니다. 첫 번째 시도 중입니다. 작동하도록 설정하면 답변을 게시합니다! – mikera

+3

두 번째 작업을 수행하려면 요청/응답 맵 위에 HttpServletRequest/Response를 구현하는 개체를 만들어야합니다. 또는 기존의 구현 (예 : http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/MockHttpServletRequest.html)을 사용하는 것이지만 reify를 사용하여 구현하는 것이 더 간단하다고 생각합니다. 리치 히치키 (Rich Hickey)가 "그 조롱 대상들, 그들은 당신을 조롱하고있다"고 말하면서, 상태있는 모의 객체를 다룬다! – cgrand

답변

8

좋아요. 이제이 기능이 작동합니다. 올바른 방향으로 포인터를 보내 주셔서 감사합니다!

내 솔루션에는 필터링 된 서블릿과 필터 체인에 대한 프록시를 만드는 것이 포함되었습니다. 관심있는 사람을위한 아래의 코드 .....

(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

web.xml 파일에 필터 정의를 추가 할 필요가 없습니까? – Chiron