Intercepting the processing of requests

In an MVC environment often concrete controllers and methods on them are called. But what do you do with stuff that has to be done on every request? Or stuff that has to be done when a certain request parameter is set? A basic controller which all other controllers extend does not seem to be a good solution. This is where pre- and postinterceptors come into play.

The concept of them is to do work before the request is processed (preinterceptors) and after the process is processed and before the result is sent back to the user (postinterceptors). Because they get instances of the request, session and response classes they are very powerful. They even have the possibility to cancel the request and to prevent the processor from being executed (in case of preinterceptors).

In Stubbles the stubFrontController takes care of calling pre- and postinterceptors. Before executing the processor it calls every preinterceptor via its preProcess() method. If one preinterceptor cancels the request via stubRequest::cancel() the front controller stops calling further preinterceptors and sends the response back to the user without calling the processor and the postinterceptors. After executing the processor and if the processor did not cancel the request it calls every postinterceptor via its postProcess() method. Again, subsequent postinterceptors are not called if a postinterceptor cancels the request. Finally, the response is send back to the user.

Creating a pre- or postinterceptor

To create a pre- or postinterceptor you simply have to implement the stubPreInterceptor or stubPostInterceptor interface. Because the methods of both interceptors differ you can even combine them in one class.

Configuring the front controller with interceptors

The front controller's constructor takes a stubInterceptorInitializer as second argument. This initializer must take care of returning the list of pre- and postinterceptors. Stubbles offers a default implementation, the stubInterceptorXJConfInitializer which can be configured via xml files:

<?xml version="1.0" encoding="iso-8859-1"?>
<xj:configuration
    xmlns:xj="http://xjconf.net/XJConf"
    xmlns="http://stubbles.net/ipo/interceptors">
  <preInterceptors>
    <preInterceptor type="net::stubbles::websites::xml::stubShowLastXMLInterceptor" />
  </preInterceptors>
  <postInterceptors>
    <postInterceptor type="net::stubbles::websites::xml::stubShowLastXMLInterceptor" />
    <postInterceptor type="net::stubbles::websites::xml::stubXMLPostInterceptor" />
  </postInterceptors>
</xj:configuration>

Here, one preinterceptor and two postinterceptors are configured. To configure an interceptor you just use the preInterceptor or postInterceptor tag and set the concrete class via the type attribute where the full qualified classname must be supplied. The initializer will take care of loading the class and instantiating it.

Create your own interceptor initializer

To create your own interceptor initializer you just need to implement the stubInterceptorInitializer interface:

  • init(): Here the initializing of all interceptors should be done.
  • setDescriptor(): The descriptor enables you to have different configurations. If your processor resolver offers the possibility of having different processors it should be able to configure the interceptors dependend on the processors, because some interceptors may only make sense if a certain processor is used in the request. The front controller will ask the processor for a descriptor, which then in turn will be set in the interceptor initializer via this method.
  • getPreInterceptors(): this should return a list containing all preinterceptor instances that should be executed.
  • getPostInterceptors(): this should return a list containing all postinterceptor instances that should be executed.