2011-12-20 66 views
29

Tôi đang viết bộ lọc để thực hiện một tác vụ cụ thể nhưng tôi không thể đặt mẫu url cụ thể cho bộ lọc của mình. Ánh xạ bộ lọc của tôi như sau:Chúng tôi có thể sử dụng cụm từ thông dụng trong mẫu URL web.xml không?

<web.xml> 
    <filter> 
    <filter-name>myFilter</filter-name> 
    <filter-class>test.MyFilter</filter-class> 
    </filter> 

    <filter-mapping> 
    <filter-name>myFilter</filter-name> 
    <url-pattern>/org/test/*/keys/*</url-pattern> 
    </filter-mapping> 
</web-app> 

Url mẫu của tôi [ /org/test/ * /keys/ * ] không hoạt động như tôi mong đợi.

tôi kêu gọi các url từ trình duyệt như:

http://localhost:8080/myapp/org/test/SuperAdminReport/keys/superAdminReport.jsp 
http://localhost:8080/myapp/org/test/Adminreport/keys/adminReport.jsp 
http://localhost:8080/myapp/org/test/OtherReport/keys/otherReport.jsp 

Vì vậy, cho các URL trên mô hình bộ lọc phải phù hợp. Làm thế nào tôi có thể đạt được điều này?

+3

Theo như tôi biết, bạn chỉ có thể sử dụng nội dung của một thư mục cụ thể ('path/to/my/folder/*') hoặc một phần mở rộng cụ thể ('* .do') trong urlpattern. – bdares

+0

vui lòng tham khảo câu trả lời được chấp nhận trong [câu hỏi này] (http://stackoverflow.com/q/26732/922954) – aishwarya

Trả lời

6

Url của bạn sẽ không hoạt động vì nó không phải là mẫu url hợp lệ. Bạn có thể tham khảo các câu trả lời sau

URL spec

0

trong web.xml để lập bản đồ servlet, bạn có thể áp dụng ký tự đại diện duy nhất tại start hoặc end, nếu bạn cố gắng áp dụng các ký tự đại diện ở giữa các bản đồ sẽ không được chọn.

3

Điều đó sẽ không hoạt động, không thể sử dụng regex ở đó. Hãy thử sử dụng các url này cho các ứng dụng của bạn:

http://localhost:8080/myapp/org/test/keys/SuperAdminReport/superAdminReport.jsp 
http://localhost:8080/myapp/org/test/keys/Adminreport/adminReport.jsp 
http://localhost:8080/myapp/org/test/keys/OtherReport/otherReport.jsp 

Và cấu hình này cho web.xml của bạn:

<filter-mapping> 
    <filter-name>myFilter</filter-name> 
    <url-pattern>/org/test/keys/*</url-pattern> 
</filter-mapping> 
35

Không, bạn không thể sử dụng một regex đó. Theo v2.4 Java Servlet Specification (phần srv.11.1), url-con đường được hiểu như sau:

  • Một chuỗi bắt đầu bằng một '/' nhân vật và kết thúc bằng một '/ *' hậu tố được sử dụng để lập bản đồ đường dẫn.
  • Chuỗi bắt đầu bằng tiền tố ‘*.’ Được sử dụng làm bản đồ tiện ích mở rộng.
  • Chuỗi chỉ chứa ký tự '/' cho biết servlet "mặc định" của ứng dụng. Trong trường hợp này đường dẫn servlet là yêu cầu URI trừ đi đường dẫn văn bản và thông tin đường dẫn là rỗng.
  • Tất cả các chuỗi khác chỉ được sử dụng để đối sánh chính xác.

Không cho phép regex. Thậm chí không có thẻ hoang dã phức tạp.

0

Các câu trả lời trước là chính xác trong đó mẫu url chỉ có thể bắt đầu hoặc kết thúc bằng ký tự đại diện thẻ và do đó sức mạnh thực sự của regex không thể được sử dụng. Tuy nhiên, tôi đã giải quyết vấn đề này trên các dự án trước bằng cách tạo một bộ lọc mặc định đơn giản chặn tất cả các yêu cầu và bộ lọc chứa regex để xác định xem nên áp dụng logic tiếp theo hay không. Tôi thấy rằng có rất ít hoặc không có sự suy giảm hiệu suất với phương pháp này.

Dưới đây là ví dụ đơn giản có thể được cải thiện bằng cách di chuyển mẫu regex sang thuộc tính bộ lọc.

Cấu hình bộ lọc trong web.xml:

<filter> 
    <filter-name>SampleFilter</filter-name> 
    <filter-class>org.test.SampleFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>SampleFilter</filter-name> 
    <servlet-name>SampleServlet</servlet-name> 
</filter-mapping> 
<servlet-mapping> 
    <servlet-name>SampleServlet</servlet-name> 
    <url-pattern>/*</url-pattern> 
</servlet-mapping> 

lọc thực hiện cơ bản mà có thể sử dụng bất kỳ mô hình regex (xin lỗi, sử dụng OncePerRequestFilter tầng lớp phụ huynh Spring):

public class SampleFilter extends OncePerRequestFilter { 

    @Override 
    final protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { 
     if (applyLogic(request)) { 
      //Execute desired logic; 
     } 

     filterChain.doFilter(request, response); 
    } 

    protected boolean applyLogic(HttpServletRequest request) { 
     String path = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); 

     return PatternMatchUtils.simpleMatch(new String[] { "/login" }, path); 
    } 
} 
8

Theo ghi nhận của người khác, không có cách nào để lọc với kết hợp biểu thức chính quy chỉ sử dụng các tính năng lọc servlet cơ bản. Đặc tả servlet có khả năng được viết theo cách nó cho phép kết hợp hiệu quả các url và vì các servlet có sẵn trước các biểu thức chính quy trong java (các biểu thức chính quy đến java 1.4).

Regular expressions khả năng sẽ ít performant (không tôi đã không benchmarked nó), nhưng nếu bạn không bị hạn chế mạnh mẽ bởi thời gian xử lý và có nhu cầu kinh doanh hiệu quả để dễ cấu hình, bạn có thể làm điều đó như thế này:

trong bộ lọc của bạn:

private String subPathFilter = ".*"; 
private Pattern pattern; 

    @Override 
    public void init(FilterConfig filterConfig) throws ServletException { 
    String subPathFilter = filterConfig.getInitParameter("subPathFilter"); 
    if (subPathFilter != null) { 
     this.subPathFilter = subPathFilter; 
    } 
    pattern = Pattern.compile(this.subPathFilter); 
    } 

    public static String getFullURL(HttpServletRequest request) { 
    // Implement this if you want to match query parameters, otherwise 
    // servletRequest.getRequestURI() or servletRequest.getRequestURL 
    // should be good enough. Also you may want to handle URL decoding here. 
    } 

    @Override 
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 
    Matcher m = pattern.matcher(getFullURL((HttpServletRequest) servletRequest)); 
    if (m.matches()) { 

     // filter stuff here. 

    } 
    } 

Sau đó, trong web.xml ...

<filter> 
    <filter-name>MyFiltersName</filter-name> 
    <filter-class>com.konadsc.servlet.MyFilter</filter-class> 
    <init-param> 
     <param-name>subPathFilter</param-name> 
     <param-value>/org/test/[^/]+/keys/.*</param-value> 
    </init-param> 
    </filter> 
    <filter-mapping> 
    <filter-name>MyFiltersName</filter-name> 
    <url-pattern>/*</url-pattern> 
    </filter-mapping> 

Đôi khi cũng thuận tiện để làm cho mẫu loại trừ khớp bằng cách đảo ngược câu lệnh if trong doFilter() (hoặc thêm một tham số init khác để loại trừ các mẫu, được để lại dưới dạng tập thể dục cho người đọc.)

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