To write a web application, Java developers can use the servlet API. The servlet technology, created around 1997, is a simple and powerful framework on top of which many web applications and higher web frameworks have been created. This article shows how to write the same kind of web application in Ada.
Ada Servlet Framework
The Ada Servlet framework is provided by Ada Server Faces. It is an adaptation and implementation of the JSR 315 (Java Servlet Specification) for the Ada 05 language. The Ada API is very close to the Java API as it provides the Servlet, Filter, Request, Response and Session types with quite the same methods. It should be quite easy for someone who is familiar with Java servlets to write an Ada servlet.
The servlet API is represented by the Servlet tagged type which represents the root of all servlets. A servlet must extend this Servlet tagged type and it can override one of the Do_Get, Do_Post, Do_HeadDo_Delete, Do_Put, Do_Options or Do_Trace procedure. Each Do_XXX procedure receives a request object and a response object.
with ASF.Servlets; with ASF.Requests; with ASF.Responses; package Volume_Servlet is use ASF; type Servlet is new Servlets.Servlet with null record; -- Called by the servlet container when a GET request is received. procedure Do_Get (Server : in Servlet; Request : in out Requests.Request'Class; Response : in out Responses.Response'Class); end Volume_Servlet;
The Do_Get procedure receives the request and response as parameter. Both objects are in out parameters because the servlet implementation can modify them. Indeed, the Java servlet API allows the servlet developer to set specific attributes on the request object (This allows to associate any kind of data to the request for later use when rendering the response).
Similar to the Java API, the response is written by using the Print_Stream object that is returned by the Get_Output_Stream function.
with ASF.Streams; package body Volume_Servlet is procedure Do_Get (Server : in Servlet; Request : in out Requests.Request'Class; Response : in out Responses.Response'Class) is Output : Streams.Print_Stream := Response.Get_Output_Stream; begin Output.Write ("..."); Response.Set_Status (Responses.SC_OK); end Do_Get; end Volume_Servlet;
Note: the complete content is omitted for the clarity of this post.
With Java servlet 2.5 specification, servlets are registered exclusively through the web.xml application descriptor file. Since Java servlet 3.0, one can register servlets programmatically. With our Ada servlet, this is was we will do with the use of the Add_Servlet method.
Since the Ada runtime is not able to create dynamically an instance of any class (such as the Java newInstance method of the Java Class class), we have to create ourselves the servlet instance object and register it. The servlet instance is associated with a name.
Once registered, we have to define a mapping that tells which URL path is mapped to the servlet. This is done by the call to Add_Mapping: every URL that ends in .html will be handled by the servlet.
The Ada Server Faces framework provides a Web container in which the application must be registered (similar to the Java Web container). The registration is done by the Register_Application call which also specifies the URL prefix for the web application (Every URL starting with /volume will be served by this application).
with ASF.Server.Web; with ASF.Servlets; with Volume_Servlet; procedure Volume_Server is Compute : aliased Volume_Servlet.Servlet; App : aliased ASF.Servlets.Servlet_Registry; WS : ASF.Server.Web.AWS_Container; begin -- Register the servlets and filters App.Add_Servlet (Name => "compute", Server => Compute'Unchecked_Access); -- Define servlet mappings App.Add_Mapping (Name => "compute", Pattern => "*.html"); WS.Register_Application ("/volume", App'Unchecked_Access); WS.Start; delay 600.0; end Volume_Server;
Compilation and Execution
The compilation of the Ada servlet example is done using a GNAT project file.
$ gnatmake -Psamples
It produces the volume_server which is our web server.
After the server is started, point your browser to http://localhost:8080/volume/index.html to look at the result.