In this tutorial we're going to build a simple forum page from scratch. The functionality will be very limited:
- view forum thread names
- start a new thread
- view posts of the selected thread
- add a post to the selected thread
The web app must also meet these requirements:
- The data must be stored on disk in regular files. It is recommended to process the files using DataOutputStream/DataInputStream. You can use one file for the thread names and a separate file for each thread.
- All HTTP responses must contain appropriate HTTP headers.
Each request and response contains HTTP headers.
Headers are a set of key-value pairs that contain additional information for the request/response.
The headers are never rendered, but the server or browser may use them in other ways.
You can manually set response headers from a servlet by using response.setHeader("header-name", "header-value");
.
The headers are visible in the browser developer tools' network tab.
Header | Description |
---|---|
Content-Length | Indicates the size of the request/response body in bytes |
Content-Type | Indicates the media type of the resource (e.g. text/html; charset=utf-8 , text/plain , application/octet-stream ) |
Location | indicates the URL to redirect a page to (the response body can be empty) |
(there are many more headers, but we don't need them for now)
Our forum page servlets should set the Content-Type
and Content-Length
headers.
The Content-Type must always include the charset specifier for text data.
For html pages you should almost always use text/html; charset=utf-8
.
Note that the Content-Length must specify the content length in bytes, not the number of characters.
Try to set the content type to text/plain
for a html page and see how the browser renders it.
The request contains the Request-URI and the method name. The response doesn't contain either of them. Instead, the response has a status code and a reason phrase.
The status code is a 3-digit integer that shows the result of the request. The reason phrase is a short textual description of the reason code. The most common status codes (along with their reason phrases) are 200 (OK), 404 (Not Found), and 302 (Found). There are more status codes with each having a different meaning. Most status codes have a default reason phrase, but you can always override it manually.
Code | Description |
---|---|
1xx | Informational - Request received, continuing process |
2xx | Success - The action was successfully received, understood, and accepted |
3xx | Redirection - Further action must be taken in order to complete the request |
4xx | Client Error - The request contains bad syntax or cannot be fulfilled |
5xx | Server Error - The server failed to fulfill an apparently valid request |
Note that when sending the Location header, then the status code must be set to 3xx.
See the MDN documentation for details.
You can set the status code in the servlet using response.setStatus(302);
.
The HttpServletResponse contains a constant for most status codes, e.g. HttpServletResponse.SC_FOUND
is a constant for 302.
Implement the forum.
GET /
should show a html page that shows all the names of all forum threads.GET /
should include a form for starting a new forum thread. The data should be handled byPOST /
. The browser should be redirected to/threads/threadName
after thePOST
(see headers).GET /threads/threadName
should show all the posts in the forum thread with the given name. Create a separate servlet for this. If the thread is not found, then send a status 404 response.GET /threads/threadName
should include a form for adding a new post to the given thread. The data should be handled byPOST /threads/threadName
. The response shouldn't be a redirect, but should instead immediately render the same view asGET /threads/threadName
.- Each forum thread name showed on
GET /
should be a link to the corresponding/threads/threadName
view.
Note that threadName
is a variable. If you have threads "apples" and "oranges", then you could GET /threads/apples
or POST /threads/oranges
.
Additionally:
- Each response should have the Content-Type and Content-Length headers set.
- Each page should include a css stylesheet (can be shared between the pages) to make it look reasonable.
Hints:
- Send
GET
requests using<a>
elements. - Send
POST
requests using<form>
elements. - Data sent from
doGet
anddoPost
usinggetWriter
/getOutputStream
is rendered in the browser. HttpServletRequest
objects contain the Request-URI (getRequestURI
), request headersgetHeader
and the request bodygetInputStream
sent by the browser. You cannot set headers manually when sending requests using<a>
or<form>
.HttpServletResponse
contains the response code, response headers and the response body sent by the server. You can set all those values manually in the servlet.- Each request ja response are completely independency and don't know anything about earlier request or responses.
- Writing HTML in a servlet is ugly - we'll see how to get rid of it in the next tutorial.
- You can debug the servlets from the IDE. Open the maven toolbar, find plugins, jetty, jetty-run; right click and select Debug. See IntelliJ docs if you can't find it.
- You don't need to create a new servlet for each thread.
Recall from the previous tutorial the wildcard servlet mapping
@WebServlet("/users/*")
. - Don't use
<br/>
for vertical spacing. Use padding and margin instead. - Learn new CSS properties:
border
,color
,background-color
,border-radius
,box-shadow
.