Conditional SDL Experience Manager (XPM) Filters Per Environment
By Jonathan Primmer
Have you ever wanted to deploy the same Java WAR to multiple SDL environments but couldn’t because your WAR contains a web.xml file containing SDL’s XPM filters?
Typically it’s possible to configure your build process to generate the WAR per environment but we didn’t have that luxury.
Instead, we used a CompositeFilter to chain the XPM Page and Binary filters together with conditional logic to check an environment.properties file to decide if the chain should be triggered. This way our web.xml stays the same per environment with our environment.properties file containing an entry to tell us if XPM is enabled.
First we create a custom filter to instantiate the CompositeFilter via conditional logic
@Component("SdlXpmWrapperFilter") public class SdlXpmWrapperFilter implements Filter { @Autowired @Qualifier("applicationProperties") protected ApplicationProperties applicationProperties; static LoggerUtil logger = LoggerUtil.getInstance(SdlXpmWrapperFilter.class); private CompositeFilter compositeFilter; private String isXpmEnabled; public void init(FilterConfig config) throws ServletException { logger.debug("in SdlXpmWrapperFilter init()"); //replace this with your own method of getting environment specific variables this.isXpmEnabled = applicationProperties.getMessage("is.xpm.enabled"); if(("true").equalsIgnoreCase(this.isXpmEnabled)) { this.compositeFilter = new CompositeFilter(); List<Filter> filters = new ArrayList<>(); filters.add(new ClientPageContentFilter()); filters.add(new ClientBinaryContentFilter()); compositeFilter.setFilters(filters); compositeFilter.init(config); } } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { logger.debug("in SdlXpmWrapperFilter doFilter()"); if(("true").equalsIgnoreCase(this.isXpmEnabled)) { logger.debug("SDL XPM is enabled on this environment."); this.compositeFilter.doFilter(req, resp, chain); } else { chain.doFilter(req, resp); } } @Override public void destroy() { this.compositeFilter.destroy(); } }
Add the custom filter to the web.xml instead of directly adding com.sdl.web.preview.client.filter.ClientPageContentFilter and com.sdl.web.preview.client.filter.ClientPageContentFilter
<filter> <filter-name>SdlXpmWrapperFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>SdlXpmWrapperFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Finally add the following to the environment.properties files
is.xpm.enabled=false
Notice that we have only one filter in our web.xml which conditionally executes both the Page and Binary filters, meaning that they run on the same filter-mapping. In reality, you may wish to create two custom filters if your Page and Binary filters are on different filter-mappings.
You can find the source files here https://bitbucket.org/jonathanprimmer/sdl-8.5-conditional-xpm-filters-java
Related posts

A Recap of Tridion Expert Summit 2020 – Day 2
Here’s a full recap on Day 2 of Tridion Expert Summit 2020.

Hacking the Tridion UDP Library
Follow along as our Tridion Practice Lead, Damian Jewett, walks through how to hack the Tridion UDP library.

A Recap of Tridion Expert Summit 2020 – Day 1
A detailed overview of SDL’s expert summit, TXS2020.