How to Exclude Some Concrete Urls from <Url-Pattern> Inside <Filter-Mapping>

Can I exclude some concrete urls from url-pattern inside filter-mapping ?

The standard Servlet API doesn't support this facility. You may want either to use a rewrite-URL filter for this like Tuckey's one (which is much similar Apache HTTPD's mod_rewrite), or to add a check in the doFilter() method of the Filter listening on /*.

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

You can if necessary specify the paths-to-be-ignored as an init-param of the filter so that you can control it in the web.xml anyway. You can get it in the filter as follows:

private String pathToBeIgnored;

public void init(FilterConfig config) {
pathToBeIgnored = config.getInitParameter("pathToBeIgnored");
}

If the filter is part of 3rd party API and thus you can't modify it, then map it on a more specific url-pattern, e.g. /otherfilterpath/* and create a new filter on /* which forwards to the path matching the 3rd party filter.

String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
chain.doFilter(request, response); // Just continue chain.
} else {
request.getRequestDispatcher("/otherfilterpath" + path).forward(request, response);
}

To avoid that this filter will call itself in an infinite loop you need to let it listen (dispatch) on REQUEST only and the 3rd party filter on FORWARD only.

See also:

  • How to prevent static resources from being handled by front controller servlet which is mapped on /*
  • How to handle static content in Spring MVC?

Exclude particular URL in servlet filter

This isn't possible via <url-pattern> configuration.

You've basically 2 options:

  1. Make <url-pattern> more specific. E.g. move all those resources wich really need to be filtered in a specific folder like /app and set the <url-pattern> to /app/*. Then you can just put the excluded page outside that folder.

  2. Check for the request URI in the filter and just continue the chain if it represents the excluded page.

    E.g.

    String loginURL = request.getContextPath() + "/login.jsp";

    if (request.getRequestURI().equals(loginURL)) {
    chain.doFilter(request, response);
    }
    else {
    // ...
    }

In a web.xml url-pattern matcher is there a way to exclude URLs?

I think you can try this one:

@WebFilter(filterName = "myFilter", urlPatterns = {"*.xhtml"})
public class MyFilter implements Filter {

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
String path = ((HttpServletRequest) request).getServletPath();

if (excludeFromFilter(path)) chain.doFilter(request, response);
else // do something
}

private boolean excludeFromFilter(String path) {
if (path.startsWith("/javax.faces.resource")) return true; // add more page to exclude here
else return false;
}
}

Exclude filter from certain url's

One solution should be the SpringSecurity (was Acegi Security) approach: make your url-pattern includes everything and exclude undesidered patterns in your filter body.

How to exclude some url from jersey filter?

Name binding filters

Instead of excluding URIs from a global filter, you could consider using a name binding filter to select the endpoints your filter will be bound to.

Also check this answer for some examples with name binding filters.

Global filters

If you are still happy with the global filter approach, you could consider using the UriInfo interface to get details about the requested URI. Use one of the following approaches to get an instance of UriInfo:

  1. Using the @Context annotation:

    @Provider
    public class AuthFilter implements ContainerRequestFilter {

    @Context
    private UriInfo info;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
    ...
    }
    }

  1. Getting it from the ContainerRequestContext:

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
    UriInfo info = requestContext.getUriInfo();
    ...
    }

Once you have the UriInfo instance, you'll have access to a bunch of methods that may be useful:

  • getAbsolutePath(): Get the absolute path of the request.
  • getBaseUri(): Get the base URI of the application.
  • getMatchedResources(): Get a read-only list of the currently matched resource class instances.
  • getMatchedURIs(): Get a read-only list of URIs for matched resources.
  • getPath(): Get the path of the current request relative to the base URI as a string.
  • getPathSegments(): Get the path of the current request relative to the base URI as a list of PathSegment.
  • getRequestUri(): Get the absolute request URI including any query parameters.
  • relativize(URI): Relativize a URI with respect to the current request URI.
  • resolve(URI): Resolve a relative URI with respect to the base URI of the application.

For more details, check the UriInfo documentation.

If the requested URI does not match the URIs you want to apply the filter to, simply use a return instruction:

@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
UriInfo info = requestContext.getUriInfo();
if (!info.getPath().contains("secured")) {
return;
}
}

Dynamic binding

Another approach is dynamic binding. It allows you to assign filters and interceptors to the resource methods in a dynamic manner. Name binding, mentioned above, uses a static approach and changes to binding require source code change and recompilation. With dynamic binding you can implement code which defines bindings during the application initialization time.

The following example extracted from the Jersey documentation shows how to implement dynamic binding:

@Path("helloworld")
public class HelloWorldResource {

@GET
@Produces("text/plain")
public String getHello() {
return "Hello World!";
}

@GET
@Path("too-much-data")
public String getVeryLongString() {
String str = ... // very long string
return str;
}
}
// This dynamic binding provider registers GZIPWriterInterceptor
// only for HelloWorldResource and methods that contain
// "VeryLongString" in their name. It will be executed during
// application initialization phase.
public class CompressionDynamicBinding implements DynamicFeature {

@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (HelloWorldResource.class.equals(resourceInfo.getResourceClass())
&& resourceInfo.getResourceMethod().getName().contains("VeryLongString")) {
context.register(GZIPWriterInterceptor.class);
}
}
}

The binding is done using the provider which implements the DynamicFeature interface. The interface defines one configure method with two arguments, ResourceInfo and FeatureContext.

ResourceInfo contains information about the resource and method to which the binding can be done. The configure method will be executed once for each resource method that is defined in the application. In the example above the provider will be executed twice, once for the getHello() method and once for getVeryLongString() (once the resourceInfo will contain information about getHello() method and once it will point to getVeryLongString()).

If a dynamic binding provider wants to register any provider for the actual resource method it will do that using provided FeatureContext which extends JAX-RS Configurable API. All methods for registration of filter or interceptor classes or instances can be used. Such dynamically registered filters or interceptors will be bound only to the actual resource method. In the example above the GZIPWriterInterceptor will be bound only to the method getVeryLongString() which will cause that data will be compressed only for this method and not for the method getHello().

Note that filters and interceptors registered using dynamic binding are only additional filters run for the resource method. If there are any name bound providers or global providers they will still be executed.


For more details, check the Jersey documentation about filters and interceptors.



Related Topics



Leave a reply



Submit