Я хочу, чтобы некоторый конкретный фильтр был применен для всех URL за исключением одного бетона (т.е. для /*
за исключением /specialpath
).
Существует ли возможность сделать это?
пример кода:
<filter>
<filter-name>SomeFilter</filter-name>
<filter-class>org.somproject.AFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SomeFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- the question is: how to modify this line? -->
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Стандартный API сервлетов не поддерживает эту возможность. Вы можете использовать для этого фильтр rewrite-URL, например Tuckey (который очень похож на Apache HTTPD mod_rewrite
), либо добавить проверку в doFilter ( )
метод Фильтра, прослушивающего / *
.
String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
chain.doFilter(request, response); // Just continue chain.
} else {
// Do your business stuff here for all paths other than /specialpath.
}
При необходимости вы можете указать игнорируемые пути как init-param
фильтра, чтобы вы все равно могли управлять им в web.xml
. Вы можете получить его в фильтре следующим образом:
private String pathToBeIgnored;
public void init(FilterConfig config) {
pathToBeIgnored = config.getInitParameter("pathToBeIgnored");
}
Если фильтр является частью стороннего API и, следовательно, вы не можете его изменить, то сопоставьте его с более конкретным URL-шаблоном
, например / otherfilterpath / *
и создайте новый фильтр на / *
, который перенаправляет на путь, соответствующий стороннему фильтру.
String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
chain.doFilter(request, response); // Just continue chain.
} else {
request.getRequestDispatcher("/otherfilterpath" + path).forward(request, response);
}
Чтобы этот фильтр не вызывал себя в бесконечном цикле, вам нужно позволить ему прослушивать (отправлять) только REQUEST
, а стороннему фильтру - только FORWARD
.
Я не думаю, что вы можете, единственная другая альтернатива конфигурации - перечислить пути, которые вы хотите отфильтровать, поэтому вместо / *
вы можете добавить некоторые для / this / *
и / that / *
и т. Д., Но это не приведет к достаточному решению, когда у вас есть много таких путей.
Что вы можете сделать, так это добавить параметр к фильтру, предоставляющий выражение (например, регулярное выражение), которое используется для пропуска функции фильтра для сопоставленных путей. Контейнер сервлета по-прежнему будет вызывать ваш фильтр для этих URL-адресов, но у вас будет лучший контроль над конфигурацией.
Править
Теперь, когда вы упомянули, что не можете управлять фильтром, вы можете либо унаследовать от этого фильтра, вызывая super
методов в его методах, кроме тех случаев, когда путь URL-адреса вы хотите пропустить присутствует и следуйте цепочке фильтров, например, предложенной @BalusC, или создайте фильтр, который создает экземпляр вашего фильтра и делегирует его при тех же обстоятельствах. В обоих случаях параметры фильтра будут включать как параметр выражения, который вы добавляете, так и параметры фильтра, от которого вы наследуете или которому делегируете.
Преимущество создания делегирующего фильтра (оболочки) заключается в том, что вы можете добавить класс фильтра обернутого фильтра в качестве параметра и повторно использовать его в других ситуациях, подобных этой.