web-dev-qa-db-ja.com

web.xml URLパターンで正規表現を使用できますか?

特定のタスクを実行するフィルターを作成していますが、特定のURLパターンをフィルターに設定できません。私のフィルターマッピングは次のとおりです。

 <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パターン[ /org/test/ * /keys/ * ]が期待どおりに機能していません。

私は次のようにブラウザからURLを呼び出しています:

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

したがって、上記のURLの場合、フィルターパターンは一致する必要があります。どうすればこれを達成できますか?

32
Satya

いいえ、そこで正規表現を使用することはできません。 Java Servlet Specification v2.4(セクションsrv.11.1)によると、url-pathは次のように解釈されます。

  • 「/」文字で始まり「/ *」接尾辞で終わる文字列は、パスマッピングに使用されます。
  • 「*。」プレフィックスで始まる文字列は、拡張マッピングとして使用されます。
  • 「/」文字のみを含む文字列は、アプリケーションの「デフォルト」サーブレットを示します。この場合、サーブレットパスはリクエストURIからコンテキストパスを引いたものであり、パス情報はnullです。
  • 他のすべての文字列は、完全一致にのみ使用されます。

正規表現は許可されていません。複雑なワイルドカードすらありません。

41
Stephen C

他の人が述べたように、基本的なサーブレットフィルター機能のみを使用して正規表現一致でフィルターする方法はありません。サーブレット仕様は、URLの効率的なマッチングを可能にする方法で記述されている可能性があります。サーブレットは、Java(正規表現がJava 1.4)。

正規表現はパフォーマンスが低下する可能性があります(ベンチマークは行っていません)が、処理時間に強く制約されておらず、構成を簡単にするためにパフォーマンスを犠牲にしたい場合は、次のようにします。

フィルター内:

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

    }
  }
_

web.xmlで...

_  <filter>
    <filter-name>MyFiltersName</filter-name>
    <filter-class>com.example.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>
_

doFilter()のifステートメントを反転することで、パターンから一致を除外することも便利です(または、excludesパターンの別の初期化パラメーターを追加します。これは読者の演習として残されます)。

11
Gus

有効なURLパターンではないため、URLは機能しません。次の返信を参照できます

RL仕様

5
havexz

それは機能しません、そこで正規表現を使用することはできません。アプリケーションに次のURLを使用してみてください。

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

そして、web.xmlのこの設定:

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

web.xmlサーブレットマッピングの場合、startまたはendでのみワイルドカードを適用できます。マッピングの間にワイルドカードを適用しようとすると、選択されません。

0
dku.rajkumar

Url-patternはワイルドカード文字でのみ開始または終了できるため、以前の応答は正しいため、正規表現の真の力は使用できません。

ただし、すべての要求をインターセプトする単純なデフォルトフィルターを作成することで、以前のプロジェクトでこの問題を解決しました。フィルターには、さらにロジックを適用するかどうかを決定する正規表現が含まれます。このアプローチでは、パフォーマンスの低下はほとんどないことがわかりました。

以下は、正規表現パターンをフィルター属性に移動することで拡張できる簡単な例です。

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>

任意の正規表現パターンを使用できる基本的なフィルター実装(申し訳ありませんが、SpringのOncePerRequestFilter親クラスを使用):

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