B4J Tutorial HTML Web Server

Chapter 1: Introduction​

The minimum code that we need to create a server is as following:
B4X:
Sub Process_Globals
    Public srvr As Server
End Sub

Sub AppStart (Args() As String)
    srvr.Initialize("")
    srvr.Start
    StartMessageLoop
End Sub

The default server port is 8080 if we don't specify it explicitly.
To change the port, use the following code:
B4X:
srvr.Port = 80

Use HttpsFilter to redirect the server to SSL port.
We need to add the following code"
B4X:
srvr.AddFilter("/*", "HttpsFilter", False)

Chapter 2: Serving Static Files​

By default, jServer will read any files inside www folder even you didn't specify the directory.
The server will treat this directory as the assets directory for your static or dynamic website.

Inside www folder, you can put your:
  • HTML files (e.g index.html)
  • Stylesheets, JavaScripts, Images files (e.g styles.css, app.js and icon.png)
Putting html file inside www directory allows client side access it using the full file extension.
For example, if you put an about.html inside www directory, you can access it using http://<domain root>/about.html
Accessing index.html is same as accessing the root path http://<domain root>/
Unless you set the server handler to manage this default behavior.
You can organize your files with sub folders inside www directory and the files with be served following the files system structure.

Example:
Physical files path: /home/myusername/myserverapp/www/images/icon.png (Linux) or C:\MyB4JProjects\MyServerApp\www\images\icon.png (Windows)
Public server path: http://<domain root>/images/icon.png

Chapter 3: Distribute to Production​

Once we have compiled our project in released mode, upload the www directory together with the server.jar from Objects folder to the remote server.

1770886456501.png

To run the server on a Linux VPS, we can use nohup command e.g:
Bash:
nohup /usr/bin/java -jar server.jar > debug.txt &

Chapter 4: Serving Dynamic Contents​

If we want to build a server that serve dynamic contents, we can use ServletResponse.Write to output the contents.
The contents type can be html, json, xml, or other media files.

We can use a server handler to serve a page to the client at the public path: e.g: http://<domain root>/products
We need to add the following code in AppStart:
B4X:
srvr.AddHandler("/products", "ProductsHandler", False)

Put our html files inside our project's "Files" folder during development.
These html files will be treated as our templates.
Read the contents using Files.ReadString.
B4X:
Dim Contents As String = File.ReadString(File.DirAssets, "products.html")
Remember that files put inside "Files" folder will be compiled into the jar file.

Let say we have the following line in our products.html file.
products.html:
<h3 class="success">I bought some $PRODUCT$!</h3>
The placeholder string can be replaced or serve from database queries.
ProductsHandler.bas:
Sub Class_Globals
    Private Response As ServletResponse
End Sub

Public Sub Initialize
 
End Sub

Sub Handle (req As ServletRequest, resp As ServletResponse)
    Response = resp
    Response.ContentType = "text/html"
 
    RenderProductsPage
End Sub

Sub RenderProductsPage
    Dim Contents As String = File.ReadString(File.DirAssets, "products.html")
    Contents = Contents.Replace("$PRODUCT$", "oranges")
 
    Response.Write(Contents)
End Sub

I attached a minimum test server project here to demonstrate some different implementation of a "static" and "dynamic" contents.

References:
https://www.b4x.com/android/forum/threads/server-building-web-servers-with-b4j.37172/
https://www.b4x.com/android/forum/threads/server-run-a-server-on-a-vps.60378/

If you are already familiar building web servers using B4J, consider to use the libraries and framework developed by me.
I hope they can simplify your development work.
 

Attachments

  • server.zip
    78.2 KB · Views: 27
Last edited:

Mashiane

Expert
Licensed User
Longtime User
B4X:
Sub Handle (req As ServletRequest, resp As ServletResponse)

Thank you so much for this. One of the things that I was failing to understand was this. So ServletRequest is input, i.e. what comes into the server? Just like when one types a URL on the browser that will be input that will be received by the "handler"

And the ServletResponse is what the server sends out, i.e. output, which can be written to the "page" and you see on your webapp?
 

aeric

Expert
Licensed User
Longtime User
Reupload server.zip in post #1

1. Fixed a typo in products.html
2. Added #CustomBuildAction to create dist.zip
3. Minor adjustments

Edit: Reuploaded again.
Added Conditional Compilation.
B4X:
#If Release
#CustomBuildAction: 2, %JAVABIN%\jar.exe, -cMf dist.zip www %PROJECT_NAME%.jar
#End If
 
Last edited:

aeric

Expert
Licensed User
Longtime User
B4X:
Sub Handle (req As ServletRequest, resp As ServletResponse)

Thank you so much for this. One of the things that I was failing to understand was this. So ServletRequest is input, i.e. what comes into the server? Just like when one types a URL on the browser that will be input that will be received by the "handler"

And the ServletResponse is what the server sends out, i.e. output, which can be written to the "page" and you see on your webapp?
Yes.

Client makes Request to the Server, thus the ServletRequest in the server handler is passing the incoming data to the Handle sub.
The data can be query parameters, headers, content type, request url or body text if the request is HTTP POST or PUT.
B4X:
Request.RequestURI
B4X:
Request.InputStream

When the Server finished processing the Request and wants to return the output to the Client, the Response can be send to the Client from the Server using ServletResponse.Write().
B4X:
Response.Write("<h1>Welcome!</h1>")
The String can be an HTML text provided you have set:
B4X:
Response.ContentType = "text/html"
You can also send JSON or XML with the correct MIME type.
Otherwise, we can use ServletRequest.SendError() or ServletRequest.SendRedirect().
B4X:
Response.SendError(404, "<h1>Page Not Found</h1>")
B4X:
Response.SendRedirect("index.html")
 
Last edited:
Top