HstComponent Java Class
A HstComponent can be invoked by a HstComponent container during three different request lifecycle phases: ACTION, RESOURCE and RENDER. A HstComponent is not thread-safe because the HST container creates one instance to serve concurrent requests. This means that in general you do not want to store instance variables in a HstComponent class, and if you do so, make sure that it support concurrent access. Storing request specific objects in an instance variable of a HstComponent does in general indicate a concurrency issue.
More specific:
The HST instantiates a HstComponent only once per hst component configuration. Thus assume you have 2 hst component configuration (below hst:myproject/hst:configurations/{myproject}/hst:pages or hst:myproject/hst:configurations/{myproject}/hst:components) that both have a hst:componentclassname that is com.myproject.components.Detail, then Detail.java will be instantiated twice.
An HstComponent implementation must implement the following interface:
public interface HstComponent {
/**
* Allows the component to initialize itself
*
* @param servletContext the servletConfig of the HST container servlet
* @param componentConfig the componentConfigBean configuration
* @throws HstComponentException
*/
void init(ServletContext servletContext, ComponentConfiguration componentConfig) throws HstComponentException;
/**
* This method is invoked before {@link #doBeforeRender(HstRequest, HstResponse)} method to give an HstComponent
* a chance to <i>prepare</i> any business service invocation(s).
* This method can be implemented to prepare business content objects by creating asynchronous jobs in parallel
* without having to wait each component's {@link #doBeforeRender(HstRequest, HstResponse)} execution sequentially.
*
* @param request
* @param response
* @throws HstComponentException
*/
default void prepareBeforeRender(HstRequest request, HstResponse response) throws HstComponentException {
}
/**
* Allows the component to do some business logic processing before rendering
*
* @param request
* @param response
* @throws HstComponentException
*/
void doBeforeRender(HstRequest request, HstResponse response) throws HstComponentException;
/**
* Allows the component to process actions
*
* @param request
* @param response
* @throws HstComponentException
*/
void doAction(HstRequest request, HstResponse response) throws HstComponentException;
/**
* Allows the component to do some business logic processing before serving resource
*
* @param request
* @param response
* @throws HstComponentException
*/
void doBeforeServeResource(HstRequest request, HstResponse response) throws HstComponentException;
/**
* Allows the component to destroy itself
*
* @throws HstComponentException
*/
void destroy() throws HstComponentException;
/**
* Returns the ComponentConfiguration for this component or <code>null</code>
* if not implemented by a subclass
*/
default ComponentConfiguration getComponentConfiguration() {
return null;
}
}
The most important methods are #doBeforeRender and #doAction as these are typically the only methods a custom Component implements/overrides.
In practice, a custom Component always extends the org.hippoecm.hst.component.support.bean.BaseHstComponent which in turns extends org.hippoecm.hst.core.component.GenericHstComponent. The GenericHstComponent only implements the interface methods without adding specific behavior. If there is no hst:componentclassname property defined, the GenericHstComponent will be used. The BaseHstComponent does not add behavior for doBeforeRender, doAction or doBeforeServeResource, but does add lots of common utilities. Note that #getComponentConfiguration is already implemented in the GenericHstComponent and in general never needs to be overridden.