Create a Custom Valve
Introduction
Goal
Develop a custom valve and inject it into the delivery tier's request processing pipeline.
Background
In Bloomreach Experience Manager's delivery framework (HST), requests are processed through a series of valves assembled together as a pipeline. Implementation projects can inject custom valves at any point into the default pipeline.
This page explains how to create a custom valve and inject it into the default request processing pipeline using Spring configuration.
The default pipeline is defined as DefaultSitePipeline in classpath:/org/hippoecm/hst/site/container/SpringComponentManager-pipelines.xml.
Details
A custom valve is implemented as a Java class extending org.hippoecm.hst.container.valves.AbstractOrderableValve. In the Spring bean definition for the custom valve, the properties beforeValves and afterValves can be used to specify where in the existing pipeline the custom valve should be injected. To enable other valves to position themselves relative to the custom valve, the bean definition should also define the property valveName.
Typically, beforeValves and afterValves each specify a single valve but both accept a comma-separated list of valves as well. The valveName, as a best practice, should be equal to the Spring bean id (in case of no id, use a logical name, like the camel case class name).
An example bean definition for a custom valve (full example below):
<bean id="myCustomValve" class="org.example.container.MyCustomValve"> <property name="valveName" value="myCustomValve" /> <property name="afterValves" value="securityValve, subjectBasedSessionValve"/> <property name="beforeValves" value="pageCachingValve"/> </bean>
Example
This example shows a custom valve class MyCustomValve that is injected into the existing HST DefaultSitePipeline after the securityValve and before the pageCachingValve.
Create a Custom Valve Class
In the site/components module of your project, create a Java class MyCustomValve and make it extend AbstractOrderableValve.
site/components/src/main/java/org/example/container/MyCustomValve.java
package org.example.container; import org.hippoecm.hst.container.valves.AbstractOrderableValve; import org.hippoecm.hst.core.container.ContainerException; import org.hippoecm.hst.core.container.ValveContext; public class MyCustomValve extends AbstractOrderableValve { @Override public void invoke(ValveContext context) throws ContainerException { try { // perform custom processing here } finally { context.invokeNext(); } } }
Configure Spring to Inject the Custom Valve
In the site/components module of your project, create a Spring configuration file src/main/resources/META-INF/hst-assembly/overrides/custom-valves.xml.
Configure a myCustomValve bean for your valve class and specify the valveName, afterValves, and beforeValves properties. Inject your custom bean into the existing HST DefaultSitePipeline.
site/components/src/main/resources/META-INF/hst-assembly/overrides/custom-valves.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="myCustomValve" class="org.example.container.MyCustomValve"> <property name="valveName" value="myCustomValve" /> <property name="afterValves" value="securityValve" /> <property name="beforeValves" value="pageCachingValve" /> </bean> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject"> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="org.hippoecm.hst.core.container.Pipelines" /> <property name="targetMethod" value="getPipeline" /> <property name="arguments"> <value>DefaultSitePipeline</value> </property> </bean> </property> <property name="targetMethod" value="addProcessingValve" /> <property name="arguments"> <ref bean="myCustomValve" /> </property> </bean> </beans>
Rebuild and Restart
Rebuild and restart your project.
Request a page in the site. Your custom valve should be invoked.