Можем ли мы использовать регулярные выражения в шаблонах URL-адресов web.xml?

Я пишу фильтр для выполнения определенной задачи, но я не могу установить конкретный шаблон url для своего фильтра. Мое отображение фильтра выглядит следующим образом:

  myFilter test.MyFilter   myFilter /org/test/*/keys/*   

Мой 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-адресов выше шаблон фильтра должен совпадать. Как я могу это достичь?

Нет, вы не можете использовать регулярное выражение. Согласно спецификации Java Servlet v2.4 (раздел srv.11.1), URL-адрес интерпретируется следующим образом:

  • Строка, начинающаяся с символа ‘/’ и заканчивающегося суффиксом ‘/ *’, используется для сопоставления пути.
  • Строка, начинающаяся с символа ‘*.’ префикс используется как расширение.
  • Строка, содержащая только символ «/», указывает «сервлет» по умолчанию приложения. В этом случае путь сервлета – это URI запроса, минус контекстный путь, а информация о пути – null.
  • Все остальные строки используются только для точных совпадений.

Регексы не допускаются. Даже не сложные дикие карты.

Как отмечают другие, нет возможности фильтровать с регулярным выражением, используя только основные функции фильтра сервлетов. Спецификация сервлета, вероятно, написана так, чтобы обеспечить эффективное сопоставление URL-адресов, а также потому, что servlets предшествуют доступности регулярных выражений в 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 …

   MyFiltersName com.konadsc.servlet.MyFilter  subPathFilter /org/test/[^/]+/keys/.*    MyFiltersName /*  

Иногда также удобно заставить шаблон исключать совпадение, инвертируя оператор if в doFilter() (или добавляя еще один параметр init для исключений шаблонов, который остается в качестве упражнения для читателя).

Ваш url не будет работать, поскольку это не действительный шаблон URL. Вы можете обратиться к следующему ответу

Спецификация URL

Это не сработает, там не может использоваться регулярное выражение. Попробуйте использовать эти 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:

  myFilter /org/test/keys/*  

в web.xml для сопоставления сервлетов. Вы можете применять подстановочный знак только в start или в end , если вы попытаетесь применить подстановочный знак между сопоставлением, не будет выбрано.

Предыдущие ответы верны в том, что url-шаблон может начинаться или заканчиваться только символом wild-card, и поэтому истинная сила регулярного выражения не может быть использована.

Однако я решил эту проблему в предыдущих проектах, создав простой фильтр по умолчанию, который перехватывает все запросы, а фильтр содержит регулярное выражение, чтобы определить, следует ли применять дальнейшую логику. Я обнаружил, что с этим подходом не наблюдается снижения производительности.

Ниже приведен простой пример, который можно улучшить, перемещая шаблон регулярного выражения в атрибут фильтра.

Конфигурация фильтра в файле web.xml:

  SampleFilter org.test.SampleFilter   SampleFilter SampleServlet   SampleServlet /*  

Основная реализация фильтра, которая может использовать любой шаблон регулярного выражения (извините, использует родительский class Spring’s 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); } } 
Давайте будем гением компьютера.