2011-12-20 12 views
29

Piszę filtr, aby wykonać określone zadanie, ale nie mogę ustawić określonego wzorca URL-a w moim filtrze. Mój mapowanie filtr jest następujący:Czy możemy używać wyrażeń regularnych we wzorcach adresów URL web.xml?

<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> 

moja url-pattern [ /org/test/ * /keys/ * ] nie działa jak się spodziewałem.

Wołam adresów URL z przeglądarki jak:

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 

więc dla adresów URL powyżej wzorca filtra powinien odpowiadać. Jak mogę to osiągnąć?

+3

O ile mi wiadomo, możesz użyć tylko zawartości określonego folderu ('path/to/my/folder/*') lub określonego rozszerzenia ('* .do') w urlpattern. – bdares

+0

proszę zapoznać się z zaakceptowaną odpowiedzią w [to pytanie] (http://stackoverflow.com/q/26732/922954) – aishwarya

Odpowiedz

6

Twój adres URL nie działa, ponieważ nie jest prawidłowym wzorcem adresu URL. Można odwołać się do następującej odpowiedzi

URL spec

0

w web.xml dla mapowania serwletu, można zastosować wieloznaczny tylko na start lub end, jeśli starają się zastosować wieloznaczny między mapowanie nie będą zbierane.

3

To nie zadziała, nie można użyć tam wyrażenia regularnego. Spróbuj używając tych adresów URL do aplikacji:

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 

I to config dla web.xml:

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

Nie, nie można użyć tam regex. Według Java Servlet Specification v2.4 (sekcja srv.11.1), URL-path jest interpretowany w następujący sposób:

  • łańcuchem zaczynającym się od znaku '/', a kończąc na '/ *' sufiks służy do mapowania ścieżek.
  • Początek z prefiksem "*." Jest używany jako rozszerzenie.
  • Ciąg zawierający tylko znak "/" wskazuje "domyślny" serwlet aplikacji. W tym przypadku ścieżka serwletu jest identyfikatorem URI żądania minus ścieżka kontekstu, a informacja o ścieżce jest pusta.
  • Wszystkie inne ciągi są używane tylko do dokładnych dopasowań.

Brak dozwolonych wyrażeń regularnych. Nawet skomplikowane dzikie karty.

0

Dotychczasowe odpowiedzi są poprawne, że url-pattern może tylko rozpocząć lub zakończyć w charakterze dzikich kart, a więc prawdziwa moc regex nie może być używany.

Jednak mam rozwiązać ten problem na poprzednich projektów, tworząc prostą domyślny filtr, który przechwytuje wszystkie żądania i filtr zawiera regex w celu ustalenia, czy dalej logika powinna być stosowana. Zauważyłem, że z tym podejściem nie było prawie żadnego pogorszenia wydajności.

Poniżej znajduje się prosty przykład, który można ulepszyć, przenosząc wzór regex do atrybutu filtra.

konfiguracja filtra w internecie.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> 

Podstawowa implementacja filtr, który może wykorzystać dowolny wzór regex (przepraszam, wykorzystuje sprężyny OncePerRequestFilter klasa dominująca):

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

Jak wspomniano przez innych, nie ma sposobu, aby odfiltrować z dopasowywania wyrażeń regularnych przy użyciu tylko podstawowych funkcji filtru serwletów. Specyfikacja serwletu jest prawdopodobnie napisana tak, jak pozwala na sprawne porównywanie adresów URL, a ponieważ serwlety są wcześniejsze niż dostępność wyrażeń regularnych w java (wyrażenia regularne dotarły do ​​java 1.4).

Wyrażenia regularne będzie prawdopodobnie mniej wydajnych (no ja nie odwzorować go), ale jeśli nie są silnie ograniczone przez czas przetwarzania i chcą handlować wydajność dla ułatwienia konfiguracji można zrobić to tak:

w filtrze:

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. 

    } 
    } 

Następnie w 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> 

Czasami wygodnie jest również wykluczyć dopasowanie poprzez odwrócenie instrukcji if w doFilter() (lub dodać kolejny parametr początkowy dla wykluczonych wzorców, który jest pozostawiony jako ćwiczenie dla czytnika.)

Powiązane problemy