it-swarm.com.de

Können wir reguläre Ausdrücke in URL-Mustern von web.xml verwenden?

Ich schreibe einen Filter, um eine bestimmte Aufgabe auszuführen, aber ich kann kein bestimmtes URL-Muster für meinen Filter festlegen. Meine Filterzuordnung lautet wie folgt:

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

Mein URL-Muster [ /org/test/ * /keys/ * ] funktioniert nicht wie erwartet.

Ich rufe URLs aus dem Browser auf: 

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

Für die URLs oben sollte das Filtermuster passen. Wie kann ich das erreichen?

31
Satya

Nein, Sie können dort keine Regex verwenden. Gemäß der Java Servlet-Spezifikation v2.4 (Abschnitt srv.11.1) wird der URL-Pfad wie folgt interpretiert:

  • Eine Zeichenfolge, die mit einem "/" beginnt und mit einem Suffix "/ *" endet, wird für die Pfadzuordnung verwendet.
  • Eine Zeichenfolge, die mit einem Präfix "*." Beginnt, wird als Erweiterungszuordnung verwendet.
  • Eine Zeichenfolge, die nur das Zeichen "/" enthält, gibt das "Standard" -Servlet der Anwendung an. In diesem Fall ist der Servlet-Pfad der Anforderungs-URI ohne den Kontextpfad und die Pfadinformationen sind null.
  • Alle anderen Zeichenfolgen werden nur für exakte Übereinstimmungen verwendet.

Es sind keine Regexes erlaubt. Nicht einmal komplizierte Wildcards.

40
Stephen C

Wie von anderen angemerkt, gibt es keine Möglichkeit, mit der Übereinstimmung von regulären Ausdrücken nur mit den grundlegenden Servlet-Filterfunktionen zu filtern. Die Servlet-Spezifikation ist wahrscheinlich so geschrieben, dass sie ein effizientes Abgleichen von URLs zulässt, und weil Servlets die Verfügbarkeit regulärer Ausdrücke in Java voraussetzen (reguläre Ausdrücke sind in Java 1.4 eingetroffen). 

Reguläre Ausdrücke wären wahrscheinlich weniger performant (nein, ich habe es nicht bewertet), aber wenn Sie nicht durch die Verarbeitungszeit stark eingeschränkt sind und Leistung zur Vereinfachung der Konfiguration handeln möchten, können Sie dies folgendermaßen tun:

In deinem Filter:

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.

    }
  }

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

Manchmal ist es auch praktisch, das Muster durch Übereinstimmen der if -Anweisung in doFilter() auszuschließen (oder einen anderen init-Parameter zum Ausschließen von Mustern hinzuzufügen, was dem Leser als Übung bleibt.)

10
Gus

Ihre URL funktioniert nicht, da sie kein gültiges URL-Muster ist. Sie können auf die folgende Antwort verweisen

URL-Angabe

6
havexz

Das funktioniert nicht, da kann kein Regex verwendet werden. Verwenden Sie diese URLs für Ihre Anwendung:

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

Und diese Konfiguration für Ihre web.xml:

<filter-mapping>
    <filter-name>myFilter</filter-name>
    <url-pattern>/org/test/keys/*</url-pattern>
</filter-mapping>
3
I.G. Pascual

in web.xml für Servlet-Mapping können Sie Platzhalter nur bei start oder end anwenden. Wenn Sie versuchen, den Platzhalter zwischen den Zuordnungen anzuwenden, wird das Mapping nicht ausgewählt.

0
dku.rajkumar

Die vorherigen Antworten sind insofern korrekt, als ein URL-Muster nur mit einem Platzhalterzeichen beginnen oder enden kann und somit die wahre Stärke des Regex nicht verwendet werden kann.

Ich habe dieses Problem jedoch in früheren Projekten gelöst, indem ich einen einfachen Standardfilter erstellt habe, der alle Anforderungen abfängt. Der Filter enthält Regex, um zu bestimmen, ob weitere Logik angewendet werden soll. Ich stellte fest, dass bei diesem Ansatz wenig bis keine Leistungsbeeinträchtigung auftrat. 

Unten ist ein einfaches Beispiel, das durch Verschieben des Regex-Musters in ein Filterattribut verbessert werden könnte.

Filterkonfiguration in der 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>

Grundlegende Filterimplementierung, die ein beliebiges Regex-Muster verwenden könnte (sorry, verwendet die übergeordnete Klasse "OncePerRequestFilter" von 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);
    }
}
0
Adam