Architecture

Introduces Civilians core classes and concepts. How they relate to Servlet concepts.

Core classes and concepts

About servers applications

A Civilian Application runs inside a Server, receives Requests and generates Responses.
Application instances are singletons. They are embedded into a Server which represents the physical server (e.g. a web server or ServletContainer) and provides access to server resources. A Server can host one ore more applications. Server and applications are associated with a path within the phyiscal server.
The main responsibility of application instances is to provide application global resources such as database connections to your data back-end, initialize those resources at application start and clean up at shutdown.

About resources and controllers

The very nature of a web application is to expose resources which can be referenced by URLs. A request is therefore always a request for an application resource.

Civilian allows and demands restful processing of a request. Not only the request path, but also request method or verb, accepted response content type, content type of the request body, etc. can and should be taken into account when generating the response.
For instance the following request asks for a JSON representation of a resource

GET /apps/crm/customers/1345 HTTP/1.1
Accept: application/json
and the response might look like
HTTP/1.1 200 OK

Content-Type: application/json; charset=UTF-8
{"id":1345,"name":"ACME",...}

Your application can expose any number of resources and each resource should support individual RESTful processing.
Therefore

  • for each resource of your application you will implement a class derived from Controller which is responsible to process requests for its resource.
  • Special annotated methods in your controller class – "action" methods – are the entry points of request processing.
  • At runtime the framework dispatches requests to the appropriate controller and invokes the appropriate method depending on RESTful criteria:
Request Dispatched to
GET /apps/crm/users/789 HTTP/1.1
Accept: application/json
 
@Get @Produces("application/json")
com.crm.users.id.IndexController#getJson()
POST /apps/crm/users/789 HTTP/1.1
Accept: text/html
Content-Type: application/x-www-form-urlencoded
 
@Post @Produces("text/html")
com.crm.users.id.IndexController#editForm()
DELETE /apps/crm/users/789 HTTP/1.1
@Delete com.crm.users.id.IndexController#delete()
Request dispatch and routing is easily the most important feature of a web framework.
Of course you could examine the request and dispatch by hand. If your application serves only two resources, doesn't care about REST, a single Servlet with handwritten dispatch might just be enough. But obviously such an approach would not scale well. For all other more complex applications an elegant solution for resource dispatch and routing is essential.

About controllers (continued)

... MVC pattern, templates, forms, localization and more
As you already guessed, Controllers are the C in the MVC – Model View Controller – pattern.
Their job is to accept a resource request and to initiate and orchestrate request processing. When a controller has finished, a response should have been generated. This usually means:
  1. Evaluate request parameters (normal params, path params, matrix params, cookies, headers, request content)
  2. Depending on that evaluation respond with one of the following
    • an error response, or
    • a redirect or forward to another resource, or
    • response content and response headers, to be processed by the client
But controllers don't need to (and should not) implement response generation all by themselves.
Ideally they are just the glue between frontend request and back-end services:
  1. The controller extracts parameters from the request, translates them into back-end service parameters and calls all back-end services needed to fulfill the request.
  2. Services return data - the model of the MVC pattern.
  3. The controller turns the model into a view, suitable to be sent as response. This might be a JSON or XML representation of the model, or a HTML page which displays dynamic data, etc.
Civilian does not make any assumptions about your data back-end and your models. It also gives you total freedom what response to generate. But it offers the following facilities to make implementation of controllers easier:
  • Easy conversion of request parameters from strings into typed values. Special support for path parameters.
  • Support for reading and writing HTML forms using the Form class.
  • Customizable and extensible content serialization to easily convert models from and to JSON, XML, etc.
  • A powerful Template system to turn models into complex textual output like HTML
  • Integrated support for multi-language/locale-dependent applications.

About assets

Not every resource exposed by your application needs to be dynamically generated. Web applications with browser clients will most likely provide JavaScript, CSS, image resources, etc. On the server side these resources are usually stored as files and should simple be sent to the client when they are requested.
Request Returns file
GET /apps/crm/gfx/style.css HTTP/1.1
Accept: text/css,*/*;q=0.1
/tomcat/webapps/crm/gfx/style.css
Following common webapp lingo we call such static resources assets.
Civilian helps you to organize your applications assets, to define how assets are exposed as resources and to implement fast and easy processing of asset requests.

About processors

Now lets step back a little bit:
Processing of dynamic resources (by Controllers) and static resources (by Civilians asset handling) are two kinds of request processing supported by the framework. But Civilian can't know all possible ways your application wants to handle requests.

Therefore applications allow to customize request processing by the concept of request Processors which are arranged in a pipeline. Each processor in the pipeline can decide to handle the request, pass it on to the next processor in the pipeline, modify request or response to implement filter functionality, etc.

The pipeline in the example above uses the ResourceDispatch and AssetDispatch which are processor implementations to handle dynamic and static resources. IpFilter is another predefined processor which allows to accept or reject requests based on a IP whitelist. (Logger and EncryptionHandler are two fictional processors implementations provided by the example application).

Using Civilian in a Servlet Container

Civilian applications main installation target is a Servlet Container: The following table shows the main correspondence between Civilian and Servlet concepts.
Civilian Servlet Environment
Server javax.servlet.ServletContext
Application no direct counterpart
used internally to route requests to applications javax.servlet.Servlet
Processor, implementing a filter strategy javax.servlet.Filter
Request javax.servlet.http.HttpServletRequest
Response javax.servlet.http.HttpServletResponse