2010-05-10 18 views
6

Tôi đang cố gắng xây dựng một trang web đơn giản bằng Clojure/Compojure và muốn cấp dữ liệu áp dụng bộ lọc servlet cho yêu cầu/phản hồi (ví dụ: một cá thể javax.servlet.Filter tiêu chuẩn) .Sử dụng javax.servlet.Filter với Compojure

ví dụ: nếu mã nguồn hiện nay là:

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

Tôi muốn thêm một bộ lọc như thế này:

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

đâu my-filter-name là một số ví dụ độc đoán của javax.servlet.Filter.

Bất kỳ ý tưởng nào về cách thực hiện điều này một cách hiệu quả và thanh lịch?

+3

bạn có muốn áp dụng bộ lọc cho tất cả tuyến đường hoặc chỉ một số bộ lọc không? Trong trường hợp đầu tiên, có thể dễ dàng đặt bộ lọc phía trên Ring/Compojure, ở cấp Servlet. Trong trường hợp thứ hai, bạn cần phải viết (với reify hoặc proxy) một adapter mà biến một bộ lọc thành một middleware. – cgrand

+0

Cảm ơn rất hữu ích. Tôi muốn làm điều thứ hai nhưng dường như không thể thực hiện được vì các tham số yêu cầu/đáp ứng mà bộ lọc cần không được chuyển thành các tham số cho hệ thống phần mềm trung gian. Tôi đang cố gắng đầu tiên - sẽ đăng câu trả lời nếu tôi làm cho nó hoạt động! – mikera

+3

Để làm thứ hai, bạn cũng cần phải tạo ra các đối tượng thực hiện HttpServletRequest/Response trên đầu trang của các bản đồ yêu cầu/phản hồi. Hoặc sử dụng việc triển khai hiện tại (ví dụ: http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/mock/web/MockHttpServletRequest.html) nhưng tôi nghĩ rằng việc triển khai chúng dễ dàng hơn đối phó với một đối tượng giả mạo trạng thái - như Rich Hickey nói "Những đồ vật giả, họ đang chế giễu bạn"! – cgrand

Trả lời

8

Ok giờ tôi đã làm việc này! Cảm ơn cgrand cho các con trỏ đi đúng hướng!

Giải pháp của tôi liên quan đến việc tạo proxy cho servlet đã lọc và chuỗi bộ lọc. Mã bên dưới cho bất kỳ ai quan tâm .....

(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

Bạn không cần thêm định nghĩa bộ lọc của mình vào tệp web.xml? – Chiron

Các vấn đề liên quan