HST Request Processing - BloomReach Experience - Open Source CMS

This article covers a Hippo CMS version 12. There's an updated version available that covers our most recent release.

20-06-2018

HST Request Processing

1. Introduction

Pipelines are based on the inversion of control pattern. The request processing pipelines are assembled through Spring Framework configurations. HST Container is largely driven by a request/response processing data flow, much like the servlet or HTTP request/response paradigm. Requests are made by client agents such as webbrowsers and the HST Container processes the request on the thread provided by the application server. Request processing is achieved in a workflow like pipeline, where valves are plugged into the request pipeline. The workflow of the valves is configurable just like any other components in the Spring Framework configurations. Pipelines reference (via Spring Framework dependency injection) one or more valves. Valves are also bean components which can be also assembled in the Spring Framework configurations.

2. Pipeline Driven Processing

Requests to the HST Container always come in via HstFilter which parses the URL and resolves a proper mount. The request URL can be mapped to a pipeline by configuring  hst:namedpipeline property for a mount. By default, the default site pipeline aggregates HST Component pages.

 

.

3. Pipeline Architecture

In an HST based application, requests are processed through a series of Valves assembled together as a pipeline.

As described below, when a request comes, HstRequestContext is created to process the request through a pipeline.

 

.

4. Pipeline Mapping Configuration

The pipeline mapping configuration is provided in  classpath:/org/hippoecm/hst/site/container/SpringComponentManager-pipelines.xml.

<bean id="org.hippoecm.hst.core.container.Pipelines" class="org.hippoecm.hst.core.container.HstSitePipelines">
  <property name="defaultPipelineName" value="DefaultSitePipeline"/>
  <property name="pipelines">
    <map>
      <entry key="DefaultSitePipeline">
        <bean class="org.hippoecm.hst.core.container.HstSitePipeline">
          <property name="initializationValves">
            <list>
              <ref bean="initializationValve"/>
              <ref bean="cmsSecurityValve"/>
            </list>
          </property>
          <property name="processingValves">
            <list>
               <ref bean="securityValve" />
               <ref bean="subjectBasedSessionValve" />
               <ref bean="jcrSessionStatefulConcurrencyValve"/>
               <ref bean="contextResolvingValve" />
               <ref bean="localizationValve" />
               <ref bean="actionValve" />
               <ref bean="resourceServingValve" />
               <ref bean="pageInfoRenderingValve" />
               <ref bean="esiPageInfoScanningValve" />
               <ref bean="pageCachingValve"/>
               <ref bean="componentRenderingValve" />
               <ref bean="aggregationValve" />
            </list>
          </property>
          <property name="cleanupValves">
            <list>
              <ref bean="cleanupValve"/>
              <ref bean="diagnosticReportingValve"/>
            </list>
          </property>
        </bean>
      </entry>
  </property>
</bean>

As you can see above, the request processing component of HST Container actually invokes three series of valves: initializationValves, processingValves and cleanupValves. The  initializationValves contains valves which are responsible for initialization, the  processingValves contains valves which are doing core request processing, and the  cleanupValves contains valves which are responsible for cleaning up the temporary request processing data.

5. Request Handling with Components

In the previous sections, the internal pipeline processing inside HST Container has been discussed. In this section, a typical interaction between HST Container and each HST components will be discussed here to explain how the request processing is done with HST Components.

A typical page request can be depicted as follows:

 

 

In the above diagram, the following is assumed:

  • The client is requesting a page which maps to a page configuration which is composed of a root HST Component, "Parent".

  • The "Parent" component will be resolved to contain two child components at runtime: "LeftChild" and "RightChild". These two child components are siblings in this example.

  • At the time, suppose the client is submitting a form included in the "RightChild" HST Component to an HST Action URL.

The interaction sequences would be like the following in this example:

  1. Client requests to HST Container via the HST Action URL.

  2. Because the client is submitting a form by an Action URL, the Container invokes doAction() of "RightChild".

  3. The Container redirects to a render page after invoking  #doAction(). (Because the Container aggregates multiple components in a page, the Action phase should be separated from the Render phase of all components. HST Container aggregation implies PRG (POST/REDIRECT/GET) pattern.

  4. Client requests to the render page.

  5. The Container invokes  #prepareBeforeRender() of each component if implemented optionally. See Parallel HstComponent Preprocessing for details about when/how #prepareBeforeRender() method can be used optionally.

  6. The Container invokes  #doBeforeRender() of each component. The invocation order of  #doBeforeRender() is from parent to child.

  7. The Container dispatches to the render path of the template of each component. The dispatch order is from child to parent.

  8. A parent component's render page can include the rendered content of a child component. (For example, the template of the parent component can use  <hst:include /> tag to include the rendered content of its child component.)

  9. The Container writes the aggregated content to the client.

If the page did not submit a form via an Action URL, and it just request a page via GET method, then the sequence will start from 4 above.

6. HstRequest / HstResponse

During all the interactions between HST Container and HST Components,  org.hippoecm.hst.core.component.HstRequest and  org.hippoecm.hst.core.component.HstResponse objects are given to each component.

Basically, HstRequest and HstResponse are simply extending  javax.servlet.http.HttpServletRequest and  javax.servlet.http.HttpServletResponse. So, you can normally use the existing methods of those with  HstRequest and  HstResponse.

In addition,  HstRequest object provide  namespaced access to information such as the parameters and attributes for the component from the request, the  HstRequestContext and lifecycle phase. The access is  namespaced such that every  HstComponent can read and write parameters and attributes from the  HstRequest without needing to take into account other Components writing for example to the same attribute name.

With  HstResponse, the HST Component can produce HST URLs, contribute head elements and set various HTTP headers. Also, with the template associated with the component, it may delegate the generation of content to a servlet, JSP or any other templates.

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?