Можем ли мы использовать регулярные выражения в шаблонах URL-адресов web.xml?
Я пишу фильтр для выполнения определенной задачи, но я не могу установить определенный шаблон 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-адресов выше шаблон фильтра должен совпадать. Как я могу достичь этого?
Ответы
Ответ 1
Нет, вы не можете использовать регулярное выражение. Согласно спецификации Java Servlet v2.4 (раздел srv.11.1), URL-адрес интерпретируется следующим образом:
- Для сопоставления пути используется строка, начинающаяся с символа '/и заканчивая суффиксом'/*.
- Строка, начинающаяся с символа '*. префикс используется как отображение расширений.
- Строка, содержащая только символ /, указывает сервлет приложения по умолчанию. В этом случае путь сервлета является запросить URI минус контурный путь, а информация о пути - null.
- Все остальные строки используются только для точных совпадений.
Никаких регулярных выражений не допускается. Даже не сложные дикие карты.
Ответ 2
Как отмечали другие, нет способа фильтрации с сопоставлением регулярных выражений, используя только базовые функции фильтра сервлетов. Спецификация сервлета, скорее всего, написана так, чтобы обеспечить эффективное сопоставление 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>
Иногда также удобно заставить шаблон исключать совпадение, инвертируя оператор if в doFilter()
(или добавить другой параметр init для исключения шаблонов, который оставляется в качестве упражнения для читателя).
Ответ 3
Ваш url не будет работать, поскольку это не действительный шаблон URL. Вы можете обратиться к следующему ответу
Спецификация URL
Ответ 4
Это не сработает, здесь нельзя использовать регулярные выражения. Попробуйте использовать эти 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>
Ответ 5
в web.xml
для отображения сервлета. Вы можете применять подстановочный знак только в start
или end
, если вы попытаетесь применить подстановочный знак между сопоставлением, не будет выбрано.
Ответ 6
Предыдущие ответы верны в том, что url-шаблон может начинаться или заканчиваться символом wild-card, и поэтому истинная сила регулярного выражения не может быть использована.
Однако я решил эту проблему в предыдущих проектах, создав простой фильтр по умолчанию, который перехватывает все запросы, а фильтр содержит регулярное выражение, чтобы определить, следует ли применять дальнейшую логику. Я обнаружил, что с этим подходом не наблюдается снижения производительности.
Ниже приведен простой пример, который можно улучшить, перемещая шаблон регулярного выражения в атрибут фильтра.
Конфигурация фильтра в файле 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);
}
}