2. • The Sling Request Invocation Chain
• Implementing own Sling Filters
• Use Cases and Samples
2
Agenda
3. !!!WARNING!!!
3
Sling Filters are a very generic and mighty extensionpoint. When
utilizing them you should always have in mind that AEM/CQ Core
functionality relies on the data provided by Sling, manipulation
of this data therefore may break CQ.
4. The Sling Request Invocation Chain
4
How the Sling Engine processes HTTP Requests
5. FilterManager
Sling Request Invocation Chain
5
SlingMainServlet
FilterChain
Scope: REQUEST
FilterChain
Scope: COMPONENT
Filter A
Filter B
Filter C
Registered as Services
(preferably via SCR Annotation)
Component Servlet
processRequest()dispatchRequest()
INCLUDE/FORWARD
SlingRequestProcessor
7. Registration of Filters
7
• Standard Servlet Filter (javax.servlet.Filter)
– Need to be registered as Service („manually“ or SlingFilter SCR Annotation)
• Order and FilterScopes can be defined
• Order defined by Serviceranking
• Filterscopes
– REQUEST
– COMPONENT
– ERROR
– INCLUDE *
– FORWARD *
* FilterChain executes COMPONENT scope for these scopes as well.
8. SCR Annotation
8
@SlingFilter(scope = SlingFilterScope.COMPONENT, order = -10000, metatype =
false)
public class MyComponentFilter implements javax.servlet.Filter {
@Override
public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
FilterChain pChain) throws IOException, ServletException {
// Implement Filter
// continue with filter chaining
pChain.doFilter(pRequest, pResponse);
}
}
9. Filter Order
9
• Existing Filters might use the deprecated „filter.order“ instead
„service.ranking“
• NOTE: SLING-2920 was identified while verifying this behavior – look up the
mailing list for further information how to use it for now
• Existing Filters and their execution ORDER can be inspected via
– http://<instance>:<port>/system/console/status-slingfilter
10. Check Filterconditions at first place
10
public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
FilterChain pChain) throws IOException, ServletException {
if (!(pRequest instanceof SlingHttpServletRequest)) {
throw new ServletException("Request is not a Sling HTTP request.");
}
if (isFilterEnabled(slingRequest)) {
// Implement Filter-Logic
} else {
// continue with filter chaining
pChain.doFilter(pRequest, pResponse);
}
}
• Check available Information from slingRequest if Filter should do anything.
• Be aware that these checks may be performed a lot especially for COMPONENT scope
11. Accessing and Using Data in Filter
11
public void doFilter(ServletRequest pRequest, ServletResponse pResponse,
FilterChain pChain) throws IOException, ServletException {
if (!(pRequest instanceof SlingHttpServletRequest)) {
throw new ServletException("Request is not a Sling HTTP request.");
}
if (isFilterEnabled(slingRequest)) {
Resource resource = slingRequest.getResource(); // already resolved
if (null != resource) {
PrintWriter writer = pResponse.getWriter();
writer.write("<component resourceType="" + resource.getResourceType()
"">");
pChain.doFilter(pRequest, pResponse);
writer.write("</component>");
return;
}
}
pChain.doFilter(pRequest, pResponse);
}
12. Useful Wrapper Objects in Filters
12
• SlingHttpServletRequestWrapper
– Implement to override parts of the request
• E.g. Inject impersonated ResourceResolver*
• SlingHttpServletResponseWrapper
– Implement to inject additional logic to response
• E.g. inject own writer to buffer the response to perform some postprocessing
* Security-Note: Make sure you don’t create security holes this way – the request
should always respect the permissions of the current user!
13. Dispatch to other Resource
13
RequestDispatcher dispatcher =
slingRequest.getRequestDispatcher(otherResource);
dispatcher.forward(request, response);
Required in any situation where you need to redirect the request.
Note: You should be aware that a Dispatcher Forward or Include will retrigger
the FilterChain. Place such filters early in the Filterchain to prevent other
Filters to be executed twice.
16. Logging
16
• Allows to hook in Requestcentric logging at Sling Level
• It is possible to log even requests/includes of components which are not
part of the own application (like foundation components)
• Sample
– org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter
17. Measuring
17
• Since the Filterchain gets consulted at each call of a component they
provide a natural location to measure the actual usage of the system
• The concrete usecases depend on the goal of the application
• You should just add additional measuring if no other techniques like
loganalysis or available reports are not sufficient.
18. Decoration
18
• Adding generic but usecasespecific decoration to components
• Sample
– WCMDebugFilter ( for Requestparameter debug=layout)
• Further Usecase
– For specific selector: Metadata for third party systems like
• Search Parsers
• Integrating Systems (e.g. Portals)
19. Preprocessing
19
• Injecting data that needs to be available within the components
• Sample:
– WCMComponentFilter – generic logic that links CQ Authoring logic with Sling
Components
– I18nFilter – Injecting I18n Resource Bundles
• Further Usecases
– Build Java Bean and place in Request to be used via jsp:useBean and EL within
JSPs (Sepearation of businesslogic)*
* Just a proof of concept, impact of preprocessing on performance yet untested
20. Postprocessing
20
• Injecting custom writer to postprocess output
• Sample:
– RewriterFilter
• Further Usecases:
– Integration of thirt party markup (e.g. via Velocity or Freemarker)
– Injection of a generic Placeholderlogic (e.g. Personalization)
21. Manipulating Inclusions
21
• Redirecting , Skipping or manipulating further processing
• Samples:
– Mobile RedirectFilter (trigger Redirect with matching selector for device)
– TimeWarp Filter ( replacing ResourceData & corresponding Objects with Objects at
given Timestamp)
• Further Usecases
– Controlled Impersonation in Author Mode for Permissionpreview
(Publishpermissions)
– Component Level Caching (Record response to cache and answer subsequent
requests from cache)*
* Not yet verified, but might be a solution for partial caching where dispatcher caches
cannot be used
22. Some last words…
22
• The Apache Sling Stack is the core of CQ5 / AEM
• Apache Sling is an open source project that relies on an active community
• So – be part the community!
– Join the User and/or Dev Mailinglist
– File Bugs and contribute Patches
– Participate in community events to drive evolution of Apache Sling …
… like adaptTo() 2013 in Berlin (http://www.adaptto.org)
;)
23. Berlin
pro!vision GmbH
Wilmersdorfer Str. 50-51
10627 Berlin
Germany
Tel. +49 (30) 818828-50
E-Mail info@pro-vision.de
Frankfurt
pro!vision GmbH
Löwengasse 27 A
60385 Frankfurt am Main
Germany
Tel. +49 (69) 8700328-0
E-Mail info@pro-vision.de
Karim Khan
Tel. +49 (69) 8700328-0
E-Mail kkhan@pro-vision.de
Contact
23