Filters


What is a Sling Filter?

Sling filters are basically OSGi services which are implementing javax.servlet.Filter interface. They are mostly used for authentication of request, post processing of markup or adding/modifying some request parameters etc. Sling supports filters by applying filter chains to the requests before actually dispatching to the servlet or script for processing. This sentence could be better described by the below image:

filtersss


Two service properties are relevant to define a Sling filter :

  • sling.filter.scope – Indicates the filter chain the filter should be part of. Required! Sling won’t pick up your filter if it isn’t set.
  • service.ranking – Indicates the priority of the filter in the chain. The higher the number the earlier the filter will be invoked.

Sample Filter Implementation:


@SlingFilter(
        label = "Sample Filter",
        description = "Sample Description",
        metatype = true,
        generateComponent = true, // True if you want to leverage activate/deactivate
        generateService = true,
        order = 0, // The smaller the number, the earlier in the Filter chain (can go negative); 
        scope = SlingFilterScope.REQUEST) // REQUEST, INCLUDE, FORWARD, ERROR, COMPONENT (REQUEST, INCLUDE, COMPONENT)
@Properties({
        @Property(
                label = "Vendor",
                name = "service.vendor",
                value = "SampleVendor",
                propertyPrivate = true
        )
})
public class SampleSlingFilter implements Filter {
    private static final Logger log = LoggerFactory.getLogger(SampleSlingFilter.class.getName());

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // Usually, do nothing
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        if (!(request instanceof SlingHttpServletRequest) ||
                !(response instanceof SlingHttpServletResponse)) {
            // Not a SlingHttpServletRequest/Response, so ignore.
            chain.doFilter(request, response); // This line would let you proceed to the rest of the filters. 
            return;
        }

        final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
        final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
        final Resource resource = slingRequest.getResource();

        if (resource.getPath().startsWith("/content/pqr")) {
            // Is the SlingFilterScope is REQUEST, redirects can be issued.
			
			//Write your custom code here.
            slingResponse.sendRedirect("/abc/xyz.html");
            return;
        }

        // to proceed with the rest of the Filter chain
        chain.doFilter(request, response);

    }

    @Override
    public void destroy() {
        // Usually, do Nothing
    }

    @Activate
    protected void activate(final ComponentContext componentContext) throws Exception {
        final Map<String, String> properties = (Map<String, String>) componentContext.getProperties();
    }

    @Deactivate
    protected void deactivate(ComponentContext ctx) {

    }
}

You may see the current filters implemented in your local instance using the link:
http://localhost:4502/system/console/status-slingfilter

Read More 

12 thoughts on “Filters

  1. Hey I have doubt it might not be relevant to this topic but guide please.

    Is it possible to add our own tag in dam filter ?
    To be more specific in DAM search we have filter below that tags with business,entertainment, etc.

    My qus is , is it possible to add our own tag to that list ? if yea please guide me

    TIA

    Like

  2. Hi Hashim,

    I followed your example to implement the filter, my requirement is on a web page link structure will be “/en-us/collaterals/a.pdf”. where as in AEM it resides in DAM structure it will reside in below location “/content/dam/XXX/collaterals/en/a.pdf”. below is my filter code. With this code I am seeing the blank PDF page instead of actual content. As per my requirement I should not change the end use URL, sue to this I am not able to use sendredirect. I tried with dispatch.include and dispatch.forward. Both has the same issue. Please help me what I am doing wrong.

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
    ServletException {
    if (!(request instanceof SlingHttpServletRequest) || !(response instanceof SlingHttpServletResponse)) {
    chain.doFilter(request, response); // This line would let you proceed to the rest of the filters.
    return;
    }

    final SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
    final SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
    final Resource resource = slingRequest.getResource();
    String path = resource.getPath();

    String uri = slingRequest.getRequestURI();
    String localeRegExPattern=”^/[a-z]{2}-[a-z]{2,5}/collaterals/+”;
    Pattern pattern = Pattern.compile(localeRegExPattern) ;
    Matcher matcher = pattern.matcher(uri);
    boolean matchFound = matcher.find();
    System.out.println(“::::::::::::::matchFound:::::::::::::::. “+matchFound);
    if (matchFound) {
    uri = pattern.matcher(uri).replaceAll(StringUtils.EMPTY);
    System.out.println(“::::::::::::::New URL Pattern Found. “);
    String tempURI = “/content/dam/XXX/collaterals/en/”+uri;
    System.out.println(“::::::::::::::tempURI:::::::::::::::::::::. “+tempURI);
    RequestDispatcher dispatch = request.getRequestDispatcher(tempURI);
    dispatch.include(request, response);
    //slingResponse.sendRedirect(tempURI);
    return;
    }
    else {

    chain.doFilter(request, response);
    }

    Thanks in Advance.
    Kumar

    Like

      • Hi Hashim,

        Could you please let me know how can I use sling.filter.pattern in the @SlingFilter Annotation ? I have used it like below :

        @SlingFilter(
        label = “Filter implementation”,
        metatype = true,
        generateComponent = true,
        generateService = true,
        order = 1,
        scope = SlingFilterScope.REQUEST
        )
        @Properties({
        @Property(name=”service.description”, value=”A Filter”),
        @Property(name=”sling.filter.pattern”, value=”/some/path”)
        })

        Could please help me understand if it’s correct to use sling.filter.pattern this way in AEM 6.3 to restrict the filter to run for specific url pattern or it can only be done by including custom logic inside the filter class ?

        The context behind using this is to restrict the filter to run for urls having only “xyz” in it. Eg Url: content/xyz/homepage.html.

        Also please tell me what kind of regular expression I need to use to restrict the patter according to my requirement.

        I couldn’t find a single relevant example or documention according to my requirement.

        Liked by 1 person

Leave a reply to Anirudh Anand Cancel reply