I am writing a filter to do a specific task but I am unable to set a specific url pattern to my filter. My filter mapping is as follows:
No, you can't use a regex there. According to the Java Servlet Specification v2.4 (section srv.11.1), the url-path is interpreted as follows:
- A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for path mapping.
- A string beginning with a ‘*.’ prefix is used as an extension mapping.
- A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the con- text path and the path info is null.
- All other strings are used for exact matches only.
No regexes are allowed. Not even complicated wild-cards.
That won't work, no regex can be used there. Try using this urls for your application:
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
And this config for your web.xml:
<filter-mapping>
<filter-name>myFilter</filter-name>
<url-pattern>/org/test/keys/*</url-pattern>
</filter-mapping>
in web.xml
for servlet mapping , You can apply wildcard only at the start
or the end
, if you try to apply the wildcard in between the mapping will not be picked.
The previous responses are correct in that a url-pattern can only begin or end with a wild-card character, and thus the true power of regex cannot be used.
However, I've solved this issue on previous projects by creating a simple default filter that intercepts all requests and the filter contains regex to determine whether further logic should be applied. I found that there was little to no performance degradation with this approach.
Below is a simple example that could be enhanced by moving the regex pattern to a filter attribute.
Filter configuration within the 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>
Basic filter implementation that could use any regex pattern (sorry, uses Spring's OncePerRequestFilter parent class):
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);
}
}
As noted by others, there is no way to filter with regular expression matching using only the basic servlet filter features. The servlet spec is likely written the way it is to allow for efficient matching of urls, and because servlets predate the availability of regular expressions in java (regular expressions arrived in java 1.4).
Regular expressions would likely be less performant (no I haven't benchmarked it), but if you are not strongly constrained by processing time and wish to trade performance for ease of configuration you can do it like this:
In your 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.
}
}
Then in 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>
It's also sometimes convenient to make the pattern exclude the match by inverting the if statement in doFilter()
(or add another init param for excludes patterns, which is left as an exercise for the reader.)
Your url wont work as it is not a valid url pattern. You can refer to the following reply
URL spec