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.

Did you find this page helpful?
How could this documentation serve you better?
On this page
    Did you find this page helpful?
    How could this documentation serve you better?